绑定:工作线程修改属性

本文关键字:修改 属性 线程 工作 绑定 | 更新日期: 2023-09-27 18:15:47

我有以下代码:

class Customers : BindableObject
{
    private ObservableCollection<string> _Products = new ObservableCollection<string>();
    public ObservableCollection<string> Products
    {
        get
        {
            return _Products;
        }
        set
        {
            _Products = value;
            RaisePropertyChanged("Products");
        }
    }
    private string _Name = "John";
    public string Name
    {
        get
        {
            return _Name;
        }
        set
        {
            _Name = value;
            RaisePropertyChanged("Name");
        }
    }

    public Customers()
    {
        Products.Add("George");
        Products.Add("Henry");
    }
    public void LongRunningFunction()
    {
        Name = "Boo";
        Thread.Sleep(5000);
        Name = "Peter";
    }
    public void ThreadedLongRunningFunction()
    {
        Task t = new Task(new Action(LongRunningFunction));
        t.Start();
    }

    public void LongRunningFunctionList()
    {
        Products.Add("Boo");
        Thread.Sleep(5000);
        Products.Add("Booya");
    }
    public void ThreadedLongRunningFunctionList()
    {
        Task t = new Task(new Action(LongRunningFunctionList));
        t.Start();
    }
}

BindableObject实现INotifyPropertyChanged.

在mainwindow . example .cs

public partial class MainWindow : Window
{
    Model.Customers c = new Model.Customers();
    public MainWindow()
    {
        InitializeComponent();
        gridToBindTo.DataContext = c;
    }
    private void cmdRun_Click(object sender, RoutedEventArgs e)
    {
        c.LongRunningFunction();
    }
    private void cmdRunAsync_Click(object sender, RoutedEventArgs e)
    {
        c.ThreadedLongRunningFunction();
    }
    private void cmdRunListSync_Click(object sender, RoutedEventArgs e)
    {
        c.LongRunningFunctionList();
    }
    private void cmdRunListAsync_Click(object sender, RoutedEventArgs e)
    {
        c.ThreadedLongRunningFunctionList();
    }
}

我的主窗口有一个绑定到名称的标签,和一个绑定到产品的列表框。

在两个函数的线程版本中,我不明白为什么我被允许操作一个属性'Name'(字符串),该属性在另一个线程中绑定到UI,但我不允许为ObservableCollection做同样的事情。

谁能解释一下为什么这里有区别?

绑定:工作线程修改属性

ObservableCollection不是thread safe,这就是为什么它不能跨不同的Dispatchers进行修改。但是你总是可以重写ObservableCollection使它线程安全。查看这里的示例- http://tomlev2.wordpress.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/

底线是在创建集合的UI分配器上引发collectionChangedpropertyChanged