WPF C#INotifyPropertyChanged不';别发火

WPF C#INotifyPropertyChanged不';别发火,wpf,binding,inotifypropertychanged,Wpf,Binding,Inotifypropertychanged,我正在构建一个WPF应用程序,作为其流程的一部分,它检查网络连接并在文本块中显示IP地址 现在,每当IP地址因任何原因发生更改时,我都会尝试更新TextBlock Text属性 我的IP地址更改工作正常,但我无法将InotifyProperty更改为工作状态 我阅读了所有可能的解决方案和实现,但我无法想出一个可行的代码 公共属性从Network Helper类的静态字符串中获取值。 因此,守则: public partial class MainWindow : Window, INot

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

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

我的IP地址更改工作正常,但我无法将InotifyProperty更改为工作状态

我阅读了所有可能的解决方案和实现,但我无法想出一个可行的代码

公共属性从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:

如您所见,此方法设置一个静态字符串“localIP”。然后由IpAddress属性对其进行计算


为什么IP地址更改时TextBlock Text属性未更新?

是否可能由于iPAddress的第一个字母是大写字母,因此事件没有反应

NotifyIPChanged(“IpAddress”)

公共字符串IP地址
Text=“{Binding DataContext.ipAddress}”


我认为您需要更仔细地了解WPF是如何工作的。 注意,不需要在代码隐藏中实现INotifyPropertyChanged。如果使用的是事件,则可以自动刷新目标UI元素的属性

然而,在我们的时代,使用代码隐藏并不是一个好的实践。您应该看看MVVM模式。这里有一个模型、视图和视图模型。ViewModel应实现INotifyPropertyChanged

事实上,我认为你的代码是完全错误的。命名不正确:当实现INotifyPropertyChanged时,不应仅为属性实现它,并且名称不应类似于:NotifyIPChanged,而应使用RaisePropertyChanged、NotifyPropertyChanged或OnPropertyChanged。在setters中,您不应该刷新其他内容,而应该只刷新目标属性,因为在其他情况下,违反了单一责任原则,就像您的情况一样。另一个糟糕的做法是绑定到代码隐藏


我希望这篇文章能让你更多地了解MVVM和WPF。祝你好运

将属性重命名为
IpAddress
,以便它遵守广泛接受的命名约定

public string IpAddress
{
    get { return NetworkStatus.localIP; }
    set
    {
        if (value != NetworkStatus.localIP)
        {
            NetworkStatus.localIP = value;
            NotifyPropertyChanged();
        }
    }
在通知方法的
propertyName
参数上使用
CallerMemberName
属性,这样就不必显式写入名称

using System.Runtime.CompilerServices;
...

private void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
把它绑好。当前的
DataContext
已用作绑定的源对象。不能将其添加到属性路径

<TextBlock Text="{Binding IpAddress}" ... />
并将窗口的
DataContext
分配给视图模型类的实例:

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

NotifyIPChanged(“IP地址”);应通知IPChange(“ipAddress”);或者更好的方法是更改(nameOf(ipAddress));或者考虑使用CeleReMeNeNess,然后您根本不必传递该名称。将属性重命名为“代码> IP地址< /代码>,以便它遵循广泛接受的命名约定。除此之外,
NotifyIPChanged
对于可以为任何属性名称触发PropertyChanged事件的方法来说似乎是一个奇怪的名称。此方法的典型名称为
NotifyPropertyChanged
RaisePropertyChanged
OnPropertyChanged
。感谢您的语义建议。我修好了。无论如何,应用程序行为不会改变。处理程序没有启动。绑定也是错误的。它应该是
Text=“{Binding IpAddress}”
,因为绑定的默认源已经是当前的DataContext。按照Clemens的建议执行。还是不行。真的不明白为什么。谢谢你的评论。我做到了。但这是行不通的。从你在问题中的表现来看,没有更多的话要说。尝试在
ipAddress
获取程序中放置断点,查看是否命中它。检查
NetworkStatus.localIP的值。这就是问题所在。IpAddress在应用程序启动时被调用,但在IP更改时不会被调用。但是,检测IP更改的事件工作正常。这是主要问题。感谢您对Clemens的支持。必须调用IpAddress属性的setter才能通知该属性的更改。但是,如果有某个“检测IP更改的事件”(您在问题中没有显示),它也可能直接调用
NotifyPropertyChanged(nameof(IpAddress))
。那么您如何准确设置主窗口的IpAddress属性以及从何处设置该属性呢?这是线程中的一个输入错误。我在代码中正确设置了它。
<TextBlock Text="{Binding IpAddress}" ... />
public class ViewModel : INotifyPropertyChanged
{
    public string IpAddress
    {
        get ...
        set ...
    }

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