WPF C#INotifyPropertyChanged没有启动

时间:2017-01-11 09:00:05

标签: wpf binding inotifypropertychanged

我正在构建一个WPF应用程序,作为其流程的一部分,检查网络连接并在TextBlock中显示IP地址。

现在,每当IP地址因任何原因发生变化时,我都会尝试更新TextBlock Text属性。

我的IP地址更改工作正常,但我无法让INotifyPropertyChanged工作。

我阅读了所有可能的解决方案和实现,但我无法提供有效的代码。

public属性从Network Helper类的静态字符串中获取值。 所以,代码:

    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"
                       />

更新 NetWorkStatus.cs - 静态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;
                        }

如您所见,此方法设置静态字符串&#34; localIP&#34;。然后由IpAddress属性评估。

为什么在IP地址更改时TextBlock Text属性不会更新?

3 个答案:

答案 0 :(得分:1)

将该属性重命名为IpAddress,以使其符合广泛接受的命名约定。

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

使用通知方法的CallerMemberName参数上的propertyName属性,这样您就不必明确写出名称。

using System.Runtime.CompilerServices;
...

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

正确绑定。当前DataContext已用作绑定的源对象。您不能将其添加到属性路径。

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

在下一步中,您可能希望将视图与视图模型分开,并将该属性放在单独的类中:

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

    ...
}

并将Window的DataContext分配给视图模型类的实例:

public MainWindow()
{
    InitializeComponent();
    DataContext = new ViewModel();
}

答案 1 :(得分:0)

我认为您需要仔细了解 WPF 的工作原理。 作为评论,没有必要在后面的代码中实现 INotifyPropertyChanged 。如果您正在使用事件,则可以自动刷新目标UI元素的属性。

但是,在我们这个时代,使用背后的代码并不是一个好习惯。你应该看看MVVM模式。你有一个Model,View和ViewModel。 ViewModel应该实现INotifyPropertyChanged。

事实上,您的代码在我看来是完全错误的。命名不正确:当您实现 INotifyPropertyChanged 时,您不应仅为属性实现它,并且名称不应如下所示: NotifyIPChanged ,而应使用 RaisePropertyChanged NotifyPropertyChanged OnPropertyChanged 。在setter中,您不应该刷新其他内容,而只应刷新您要定位的属性,否则会违反 Single Responsability 原则,就像您的情况一样。另一个不好的做法是绑定到 Code Behind

我希望这篇文章能让你阅读更多关于MVVM和WPF的内容。祝你好运!

答案 2 :(得分:-1)

事件是否可能没有反应,因为IpAdress的第一个字母是上限?

  

NotifyIPChanged( “<强> I pAddress”);

     

public string ipAddress
  Text =“{Binding DataContext。 i pAddress}”