[英]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.