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事件,并且正在监视传递给其事件处理函数的参数中该字符串中的值。 如果传递的名称与要查找的名称不匹配,则会忽略该通知。 当名称匹配时,它只会更新绑定到该属性的控件的值。

正如阿隆在评论中提到的,你可以使用CallerMemberAttributeOnPropertyChanged方法,以确保属性名称始终传递给方法正确。 根据这个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

上一篇: WPF Binding not updating from DispatcherTimer

下一篇: Time out when executing a search wpf