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