[英]Windows Phone data binding: cross-thread
我们在Windows Phone上使用Xaml绑定数据时遇到问题。 我创建了一个简单的示例,应该可以重现该问题。 这是我们的模型类:
public class Data : INotifyPropertyChanged
{
private int value = 0;
public int Value
{
get
{
return value;
}
set
{
this.value = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Value"));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public Data()
{
var t = new Thread(new ThreadStart(() =>
{
while (true)
{
Thread.Sleep(2000);
Value += 1;
}
}));
t.IsBackground = true;
t.Start();
}
}
它使用线程更新值属性并触发PropertyChanged事件。
现在,我想将此值属性绑定到gui控件:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Text="{Binding Path=Value}" />
</Grid>
public MainPage()
{
InitializeComponent();
DataContext = new Data();
}
当值第一次更改(并且触发了PropertyChanged事件)时,数据绑定系统尝试将Data.Value的值复制到TextBlock.Text,这将导致无效的跨线程异常,因为不会在该事件上触发ui线程。
我的问题:.NET数据绑定框架不应该认识到我要绑定到ui控件并执行线程切换吗? 我知道我可以简单地使用调度程序在主线程上触发PropertyChanged事件,但是我想让我的模型类与gui组件更分开。 有没有更好的解决方案来解决这个问题? 我无法使用DependencyObject方法,因为我们的核心项目(包含模型类)应在Windows Phone和Android上运行,并且Android不支持System.Windows-命名空间。
我喜欢这样:
public event PropertyChangedEventHandler PropertyChanged;
private void PropertyEventChanged(string propertyName)
{
if (PropertyChanged == null) return;
if (Application.OpenForms.Count > 0 && Application.OpenForms[0].InvokeRequired)
Application.OpenForms[0].Invoke(new MethodInvoker(() => PropertyChanged(this, new PropertyChangedEventArgs(propertyName))));
else
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
解决此问题的一种方法是将对调度程序的引用存储在您的视图模型上,并且如果不为null,则仅使用它执行属性更改事件。 然后,您可以在VM的构造函数中设置dispatcher属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.