2017-01-11 2 views
0

Ich baue eine WPF-Anwendung, die als Teil ihres Ablaufs auf Netzwerkkonnektivität prüft und die IP-Adresse in einem TextBlock anzeigt.WPF C# INotifyPropertyChanged startet nicht

Jetzt versuche ich die TextBlock Text-Eigenschaft jedes Mal zu aktualisieren, wenn sich die IP-Adresse aus irgendeinem Grund ändert.

Ich habe die IP-Adresse Änderung funktioniert gut, aber ich konnte INotifyPropertyChanged nicht funktionieren.

Ich habe alle möglichen Lösungen und Implementierungen gelesen, aber ich konnte keinen funktionierenden Code entwickeln.

Die öffentliche Eigenschaft erhält den Wert aus einer statischen Zeichenfolge der Network-Helper-Klasse. So ist der Code:

public partial class MainWindow : Window, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
} 

     public MainWindow() 
    { 
     InitializeComponent(); 

     DataContext = this; 
    } 

     public string ipAddress 
    { 
     get { return NetworkStatus.localIP; } 
     set 
     { 
      if (value != NetworkStatus.localIP) 
      { 
       NetworkStatus.localIP = value; 

       NotifyIPChanged("IpAddress"); 
      } 
     } 
    } 
    private void NotifyIPChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 

XAML:

<TextBlock x:Name="ipTxt"        
         TextWrapping="Wrap" 
         HorizontalAlignment="Left" 
         VerticalAlignment="Center" 
         Text="{Binding DataContext.ipAddress}" 
         Height="30" 
         Width="110" 
         Margin="-30,10,0,-10" 
         /> 

UPDATE NetWorkStatus.cs - static bool IsNetworkAvailable() ...

      if (statistics.BytesReceived > 0 || statistics.BytesSent > 0) 
         { 
          IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName()); 
          localIP = host.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork).ToString(); 
          return true; 
         } 

Wie Sie können Siehe diese Methode setzt eine statische Zeichenfolge "localIP". Dies wird dann von der IpAddress-Eigenschaft ausgewertet.

Warum wird die TextBlock Text-Eigenschaft nicht aktualisiert, wenn sich die IP-Adresse ändert?

+0

NotifyIPChanged ("IpAddress"); sollte NotifyIPChanged sein ("ipAddress"); oder noch besser NotifyIPChanged (nameOf (ipAddress)); oder erwägen Sie, CallerMemberName zu verwenden, und dann müssen Sie den Namen überhaupt nicht übergeben. – adminSoftDK

+0

Benennen Sie die Eigenschaft in 'IpAddress' um, damit sie den allgemein akzeptierten Namenskonventionen entspricht. Darüber hinaus scheint 'NotifyIPChanged' ein seltsamer Name für eine Methode zu sein, die das PropertyChanged-Ereignis für einen beliebigen Eigenschaftsnamen auslösen kann. Typische Namen für diese Methode sind 'NotifyPropertyChanged',' RaisePropertyChanged' oder 'OnPropertyChanged'. – Clemens

+0

Vielen Dank für Ihre semantischen Vorschläge. Ich habe sie repariert. Das Anwendungsverhalten ändert sich jedoch nicht. Der HF startet nicht. – user1776401

Antwort

-1

ist es möglich, dass das Event nicht reagiert, weil der erste Buchstabe von IpAdress ein Upper ist?

NotifyIPChanged ("I pAddress");

public string ipAddress
Text = "{Binding Datacontext. i pAddress}"

+0

Das war ein Tippfehler im Thread. Ich hatte es in meinem Code richtig eingestellt. – user1776401

0

Ich glaube, Sie brauchen einen genaueren Blick auf, wie WPF Arbeiten zu übernehmen. Als eine Anmerkung, gibt es keine Notwendigkeit, INotifyPropertyChanged in Code hinter zu implementieren. Wenn Sie Ereignisse verwenden, können Sie die Eigenschaften des Zieloberflächenelements automatisch aktualisieren.

Allerdings ist die Verwendung von Code hinter ist keine gute Praxis in unseren Tagen. Sie sollten sich das MVVM-Muster ansehen. Sie haben dort ein Model, View und ViewModel. Das ViewModel sollte INotifyPropertyChanged implementieren.

Tatsache ist, dass Ihr Code meiner Meinung nach absolut falsch ist. Die Namensgebung nicht in Ordnung ist: Wenn Sie implementieren INotifyPropertyChanged Sie sollten es nicht implementieren nur für eine Eigenschaft, und der Name sollte nicht so aussehen: NotifyIPChanged, stattdessen sollten Sie RaisePropertyChanged, NotifyPropertyChanged oder OnPropertyChanged. In Settors sollten Sie nicht etwas anderes aktualisieren, sondern nur die Eigenschaft, auf die Sie abzielen, da sonst das Prinzip verletzt wird, wie in Ihrem Fall.Eine schlechte Übung ist es auch, an Code hinter zu binden.

Ich hoffe, dieser Beitrag würde Sie dazu bringen, mehr über MVVM und WPF zu lesen. Viel Glück!

1

Benennen Sie die Eigenschaft in IpAddress um, damit sie den allgemein akzeptierten Namenskonventionen entspricht.

public string IpAddress 
{ 
    get { return NetworkStatus.localIP; } 
    set 
    { 
     if (value != NetworkStatus.localIP) 
     { 
      NetworkStatus.localIP = value; 
      NotifyPropertyChanged(); 
     } 
    } 

Verwenden Sie das CallerMemberName Attribut auf dem propertyName Parameter Ihrer Benachrichtigungsmethode, so dass Sie den Namen nicht explizit zu schreiben.

using System.Runtime.CompilerServices; 
... 

private void NotifyPropertyChanged([CallerMemberName] string propertyName = null) 
{ 
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
} 

Binden Sie es korrekt. Die aktuelle DataContext wird bereits als Quellobjekt der Bindung verwendet. Sie müssen es nicht zum Eigenschaftenpfad hinzufügen.

<TextBlock Text="{Binding IpAddress}" ... /> 

In einem möglichen nächsten Schritt, den Sie vielleicht den Blick von dem View-Modell trennen wollen und die Eigenschaft in einer separaten Klasse setzen:

public class ViewModel : INotifyPropertyChanged 
{ 
    public string IpAddress 
    { 
     get ... 
     set ... 
    } 

    ... 
} 

und weisen die DataContext der Fenster zu einer Instanz der Ansicht Modellklasse:

+0

Vielen Dank für Ihre Anmerkungen. Ich habe das gemacht. Aber es geht nicht zur Arbeit. – user1776401

+0

Von dem, was Sie in Ihrer Frage gezeigt haben, gibt es nicht viel mehr zu sagen. Versuchen Sie, einen Breakpoint in den IpAdress-Getter zu setzen, um zu sehen, ob er getroffen wird. Überprüfen Sie den Wert von "NetworkStatus.localIP". – Clemens

+0

Das ist das Problem. IpAddress wird am Anfang der Anwendung aufgerufen, aber nicht bei der IP-Änderung. Das Ereignis, das die IP-Änderung erkennt, funktioniert jedoch ordnungsgemäß. Das ist das Hauptproblem. Danke für Ihre Unterstützung Clemens. – user1776401

Verwandte Themen