绑定:工作线程修改属性

时间:2011-11-27 15:37:34

标签: c# wpf binding

我有以下代码:

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.xaml.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();
    }

}

我的MainWindow有一个绑定到Name的标签,以及一个绑定到Products的列表框。

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

有人可以解释为什么会有区别吗?

此致

1 个答案:

答案 0 :(得分:1)

ObservableCollection不是thread safe,这就是为什么它不能在不同的Dispatchers中修改的原因。但是你总是可以覆盖ObservableCollection以使其线程安全。请看这里的示例 - http://tomlev2.wordpress.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/

底线是提升创建集合的UI dipatcher上的collectionChangedpropertyChanged