我正在构建一个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属性不会更新?
答案 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}”