WPF 绑定到系统:布尔值未更新
本文关键字:布尔值 更新 系统 绑定 WPF | 更新日期: 2023-09-27 18:36:05
我需要时不时地更新资源值,但是绑定没有更新,如何实现 Notify 方法?
这就是我使用计时器更新资源的方式,CheckInternet.Status 返回一个布尔值。
_timer.Tick += (sender, args) =>
{
if (t < 10)
{
t++;
}
else
{
Application.Current.Resources["InternetConnected"] = new CheckInternet().Status;
t = 0;
}
CurrentTime = DateTime.Now.ToLongTimeString();
};
我假设我需要类似以下内容的东西,但是我真的不想添加要绑定到的其他属性,我是否可以只创建一个 NotifyBoolean 的实例并设置和取消设置值并通知更新而不需要其他属性?
public class NotifyBoolean : Common.NotifyUIBase
{
}
编辑 - 绑定
<TextBlock Text="{Binding Source={StaticResource InternetConnected}, Converter={StaticResource BooleanToStringConverter}, StringFormat=Internet: {0}}" />
ResourceDictionary
不会在更改资源时引发任何事件,一般来说,您不会将资源用于此目的。通常,资源用于您想要创建一次并共享的内容,例如样式或图像、画笔等内容。我什至会说,你通常不想在你的ResourceDictionary
里放一些可能在某个时候改变的东西。
建议:使用INotifyPropertyChanged
WPF 依赖于两个用于更改通知的接口:对于属性,您需要实现INotifyPropertyChanged
。对于集合,实现INotifyCollectionChanged
(或者更简单地说,只需使用 ObservableCollection<T>
,它会为您处理所有内容)。
所以你创建了一个类:
public class CheckInternetModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool m_InternetConnected;
public bool InternetConnected
{
get { return m_InternetConnected; }
set
{
m_InternetConnected = value;
OnPropertyChanged();
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
您可以将其设置为控件的DataContext
,并将绑定更改为 {Binding InternetConnected}
。
如果确实要使用资源,可以将此类的实例添加到资源中:
<Window.Resources>
<vm:CheckInternetModel x:Key="CheckInternetModel"/>
</Window.Resources>
您的绑定成为...
<TextBlock Text="{Binding InternetConnected Source={StaticResource CheckInternetModel}, Converter={StaticResource BooleanToStringConverter}, StringFormat=Internet: {0}}" />
您的timer.Tick
变成...
((CheckInternetModel)Application.Current.Resources["CheckInternetModel"]).InternetConnected = new CheckInternet().Status;
解决办法:手动使绑定失效
如果您坚持将其作为布尔值存储在资源字典中,剩下的唯一解决方案是使用 DependencyObject.InvalidateProperty
手动使绑定失效。因此,您必须为TextBlock
命名,然后从timer.Tick
处理程序中添加:
textBlock.InvalidateProperty(TextBlock.TextProperty);
但这还不够。您的绑定是StaticResource
,因此它不会查询ResourceDictionary
以再次获取资源。必须将绑定更改为:
<TextBlock Text="{Binding Source={DynamicResource InternetConnected}, Converter={StaticResource BooleanToStringConverter}, StringFormat=Internet: {0}}" />
DynamicResource
强制绑定在每次请求资源时再次查找资源,因此当您使TextProperty
无效时,它将再次从字典中检索InternetConnected
,并且它将具有新值。