WPF数据绑定马歇尔是否更改为UI线程? [英] Does WPF databinding marshall changes to the UI Thread?
问题描述
我刚刚注意到,从后台工作线程中更改我的 ViewModel
(MVVM)中的绑定属性时,我没有得到任何异常,视图被正确更新。这是否意味着我可以安全地依靠wpf数据绑定将 ViewModel
中的所有更改编组到UI线程?我想我已经读过某个地方应该确定(在 ViewModel
中), INotifyPropertyChanged.PropertyChanged
在UI线程。这个变化是在3.5还是什么?
I just noticed that when changing bound properties in my ViewModel
(MVVM) from a background worker thread I do not get any exceptions and the view is updated correctly. Does this mean I can safely rely on wpf databinding marshalling all changes in the ViewModel
to the UI Thread? I think I have read somewhere that one should make sure (in the ViewModel
) that INotifyPropertyChanged.PropertyChanged
is fired on the UI thread. Has this changed in 3.5 or something?
推荐答案
是标量,是否为集合。对于集合,您需要一个为您编排的专门的集合,或者通过调度程序
自己手动组织UI线程。
Yes for scalars, no for collections. For collections, you'll need a specialized collection that marshals for you, or manually marshal to the UI thread yourself via the Dispatcher
.
您可能已经阅读了 INotifyCollectionChanged.CollectionChanged
必须在UI线程上触发,因为 INotifyPropertyChanged.PropertyChanged
。以下是一个非常简单的例子,它为您证明了WPF marshals属性更改。
You may have read that INotifyCollectionChanged.CollectionChanged
must fire on the UI thread, because it's simply not true of INotifyPropertyChanged.PropertyChanged
. Below is a very simple example that proves WPF marshals property changes for you.
Window1.xaml.cs :
using System.ComponentModel;
using System.Threading;
using System.Windows;
namespace WpfApplication1
{
public partial class Window1 : Window
{
private CustomerViewModel _customerViewModel;
public Window1()
{
InitializeComponent();
_customerViewModel = new CustomerViewModel();
DataContext = _customerViewModel;
var thread = new Thread((ThreadStart)delegate
{
while (true)
{
Thread.Sleep(2000);
//look ma - no marshalling!
_customerViewModel.Name += "Appended";
_customerViewModel.Address.Line1 += "Appended";
}
});
thread.Start();
}
}
public abstract class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class CustomerViewModel : ViewModel
{
private string _name;
private AddressViewModel _address = new AddressViewModel();
public string Name
{
get { return _name; }
set
{
if (_name != value)
{
_name = value;
OnPropertyChanged("Name");
}
}
}
public AddressViewModel Address
{
get { return _address; }
}
}
public class AddressViewModel : ViewModel
{
private string _line1;
public string Line1
{
get { return _line1; }
set
{
if (_line1 != value)
{
_line1 = value;
OnPropertyChanged("Line1");
}
}
}
}
}
Window1.xaml :
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel>
<TextBox Text="{Binding Name}"/>
<TextBox Text="{Binding Address.Line1}"/>
</StackPanel>
</Window>
这篇关于WPF数据绑定马歇尔是否更改为UI线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!