WPF绑定不从DispatcherTimer更新
以下是我遇到的问题的简化版本。 这是一个相当普遍的问题,但我正在努力寻找解决方案。
我有一个实例化的类,我已经绑定到我的主窗口上的项目。 该类包含一个用于更新值的DispatcherTimer。 在给出的例子中,它每秒增加一个这个值。
我希望我的表单上的绑定项能够通过相应地更新其值来反映此更改,但它永远不会更新。
从阅读对StackOverflow的类似问题的其他反应,我有一种感觉,这是由于主UI线程的性质单独运行到导致增量的线程。
尽管我试图通过每次调用DispatcherTimer来更新此绑定,但我还是撞到了墙上。
以下是我希望每秒更新一次的表单元素:
<TextBox Text="{Binding val}" Width="100"/>
接下来,这是包含计时器和我的应用程序配置的类的实例:
BasicTimer basictimer;
public MainWindow()
{
InitializeComponent();
basictimer = new BasicTimer();
DataContext = basictimer;
}
最后,这是我创建的课程。 创建时,它会配置一个计时器,它用来每秒更新一次数值。 每次这个值更新时,我都希望主UI会被通知相应的更改和更新。 但是,这个消息似乎没有通过。
class BasicTimer: INotifyPropertyChanged { DispatcherTimer _timer; uint _val = 10; public uint val { get { return _val; } set { if(_val!=value) { _val = value; OnPropertyChanged("Value"); } } } public BasicTimer() { _timer = new DispatcherTimer(); _timer.Tick += new EventHandler(TimerTick); _timer.Interval = new TimeSpan(0, 0, 1); _timer.Start(); } private void TimerTick(object sender, EventArgs e) { val++; Console.WriteLine(val); } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string PropertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(PropertyName)); } }
我想我已经设法避免了忘记INotifyPropertChanged的常见陷阱,其他模型的其他绑定值工作得很好。 这只是通过我遇到麻烦的线程更新的属性。 我也尝试使用简单的定时器创建类似的定时器,但我遇到了同样的问题。
任何想法将非常感激,谢谢!
我相信你的问题是在OnPropertyChanged
的调用中:
uint _val = 10;
public uint val
{
get
{
return _val;
}
set
{
if(_val!=value)
{
_val = value;
OnPropertyChanged("Value");
}
}
}
这应该是
OnPropertyChanged("val");
OnPropertyChanged
调用中的字符串必须与该属性的名称匹配。
编辑
传递给OnPropertyChanged
的名称始终与该属性的名称匹配的原因是,数据绑定订阅了您的对象的PropertyChanged
事件,并且正在监视传递给其事件处理函数的参数中该字符串中的值。 如果传递的名称与要查找的名称不匹配,则会忽略该通知。 当名称匹配时,它只会更新绑定到该属性的控件的值。
正如阿隆在评论中提到的,你可以使用CallerMemberAttribute
在OnPropertyChanged
方法,以确保属性名称始终传递给方法正确。 根据这个StackOverflow问题的答案,你的方法看起来像这样:
protected void OnPropertyChanged([CallerMemberName] string PropertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
}
然后,您可以使用该属性的setter中的任何参数对其进行调用,并且名称始终是正确的。
正如对链接问题的答案所说,这段代码编译成IL代码,它与您在调用中对字符串进行硬编码时生成的代码完全相同,所以此技巧将始终如一,并且速度也会一样快。
链接地址: http://www.djcxy.com/p/46577.html