数据绑定值不从其他线程更新

时间:2012-03-13 17:00:57

标签: wpf data-binding .net-4.5

我有一个WPF应用程序,我在ViewModel中有以下StepCount属性,它实现了INotifyPropertyChanged,然后我将它绑定到我视图中的TextBox。

public int StepCount
{
   get { return _stepCount; } 
   set
   {
      _stepCount = value;
      OnPropertyChanged("StepCount");
   }
}

在XAML中,这是DataBinding的样子:

<TextBox Text="{Binding Path=StepCount}" />

这很有用,如果我更改了StepCount值,Textbox值会相应更新。

但是,我的问题是我有另一个增加StepCount的线程,在这种情况下,TextBox值没有更新。一旦线程结束,Textbox值就会更新为正确的值。

每当我的其他线程递增StepCount时,我需要更新Textbox值。就像现在一样,Textbox值仅在线程完成后显示更新。

另一个线程正在递增StepCount,但是在线程结束之前,UI中没有显示更改。

有什么想法吗?

更新

我感谢所有回复。这个问题令人费解,因为以前工作的代码似乎已经停止工作,就像这些特殊绑定一样。

当我安装VS 2011 Beta时,它会安装.NET 4.5 Beta Framework,当我因为怀疑它可能导致问题而卸载VS 2011 Beta时,它没有卸载.NET 4.5 Beta Framework。

我刚刚卸载了.NET 4.5框架,并对.NET 4.0框架进行了修复安装。完成这些步骤后,我的数据绑定工作正常,现在只要另一个线程增加StepCount,Textbox就会正确更新。

因此,看起来,.NET 4.5 Beta Framework可能会导致数据绑定问题。

我会通过向Microsoft提交问题来跟进。

感谢大家的回复。

2 个答案:

答案 0 :(得分:2)

正如您所发现的那样,您在View模型中将View绑定到的WPF类在UI线程中运行。

理想情况下,您应该使用WPF Dispatcher和Invoke命令更改视图模型的StepCount属性。这将适当地整理呼叫。

有关此流程的详情,请参阅this article

答案 1 :(得分:0)

刚刚测试过,一切正常

public partial class MainWindow : Window
{
    SimpleClass simpleClass = new SimpleClass(10);
    public MainWindow()
    {
        InitializeComponent();
        DataContext = simpleClass;
    }

    void IncrementViewModelProperty()
    {            
        simpleClass.StepCount += 11;
        Thread.Sleep(5000);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        //works the same
        //Thread thread = new Thread(() => IncrementViewModelProperty());
        //thread.Start();
        Action act = IncrementViewModelProperty;
        act.BeginInvoke(null, null);
    }
}

public class SimpleClass : INotifyPropertyChanged
{
    public SimpleClass(int stepCnt)
    {
        StepCount = stepCnt;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    public int StepCount
    {
        get { return _stepCount; }
        set
        {
            _stepCount = value;
            NotifyPropertyChanged("StepCount");
        }
    }
    private int _stepCount;
}

然后在xaml:

<StackPanel>
    <TextBlock Text="{Binding Path=StepCount, Mode=OneWay}" />
    <Button Content="Increment value in separate thread" Click="Button_Click" />
</StackPanel>

BUT!如果你经常快速点击按钮,你就会耗尽线程池,它实际上不会按预期更新属性。