请问WPF数据绑定马歇尔改变到UI线程?(Does WPF databinding marshall

2019-06-18 19:37发布

我只注意到我的变化绑定属性时ViewModel从后台工作线程(MVVM)我没有得到任何异常,认为是正确更新。 这是否意味着我可以放心地依靠WPF数据绑定编组中的所有更改ViewModel到UI线程? 我想我已经读的地方,应该确保(在ViewModel ),其INotifyPropertyChanged.PropertyChanged是在UI线程上发射。 这已在3.5或什么改变?

Answer 1:

是标量,没有对集合。 对于收藏,你需要一个专门的集合,为你乘警,或手动元帅到UI通过自己的线程Dispatcher

你可能已经阅读INotifyCollectionChanged.CollectionChanged必须触发的UI线程上,因为它根本就不是真正的INotifyPropertyChanged.PropertyChanged 。 下面是证明WPF编组属性更改为你一个很简单的例子。

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>


Answer 2:

相信随着.NET 2.0和早先化身执行上述的例子时,你会收到一个InvalidOperationException由于线程关联(链接张贴bitbonk的日期是2006年)。

现在,随着3.5,WPF确实出现了元帅后台线程属性更改到调度员为您服务。

因此,简而言之,取决于你在哪个靶向的.NET版本。 希望这清除了任何混乱。

我的一个老乡Lab49'ers的博客上讲述在这里,2007年:

http://blog.lab49.com/archives/1166



文章来源: Does WPF databinding marshall changes to the UI Thread?