UI上的可观察集合更改不会从后台更新,但普通属性会收到通知

D J*_*D J 5 c# wpf datagrid

我有两节课

public class ConccClass<T> : ObservableCollection<T>
{
}
Run Code Online (Sandbox Code Playgroud)

public class TestTherad: INotifyPropertyChanged
{
    private string name;
    public string Name
    { get {
        return name;
    }
        set
        {
            if (value != name)
            {
                name = value;
                RaisePropertyChanged("Name");
            }
        }
    }
    //// the notification implemented fully here
}
Run Code Online (Sandbox Code Playgroud)

现在我在我的视图模型中创建了一个'ConccClass'集合,并在视图中使用xaml上的datagrid绑定它.

问题当我在后台线程上添加一个项目而没有任何dispact时它不会反映在datagrid中.表示没有添加任何项目 Todo这个我必须在Dispatcher中添加项目.BeginInvoke的.这对我来说很有意义.

但要更新任何物品的名称,我不需要调度员.

Task.Factory.StartNew(() =>
        {
            while (true)
            {
                Thread.Sleep(100);
                {
                    this.Dispatcher.Invoke(() => this.Coll.Add(new TestTherad())); // **Works well**
                    //this.Coll.Add(new TestTherad()); // **does not work at all.**
                    this.Coll[0].Name = r.Next().ToString(); // ** without dispatcher works well.**
                }
            }
        });
Run Code Online (Sandbox Code Playgroud)

为何如此行为?

Jos*_*Ch. 5

以下是一个简短的解释:

您可能有一个绑定到可观察集合的UI元素.将元素添加到observable集合时,UI会更新以反映更改.但是,允许对UI进行更改的唯一线程是主线程.

因此,当您使用后台线程将项添加到observable集合时,UI会尝试使用后台线程进行更新,后台线程不允许对UI进行更改,并且会引发异常.

我很确定这行应该抛出异常://this.Coll.Add(new TestTherad());. 尝试在任务块内部进行调试.

当您使用调度程序时,您使用主线程进行更新,因此它可以正常工作.

对属性的更新有效,因为您只是在举办活动.框架应该监听该事件并确保自动将其分发给主线程.