我有一个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提交问题来跟进。
感谢大家的回复。
答案 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!如果你经常快速点击按钮,你就会耗尽线程池,它实际上不会按预期更新属性。