DataGrid 中未表示的 ObservableCollection<T> 的异步修改

Async modification of ObservableCollection<T> not represented in DataGrid

我已经有一段时间没和 Forms/WPF 一起工作了。如果这是一个愚蠢的问题,请原谅。

我有一个名为 myObservableObservableCollection<myClass>,其中 myClass 包含以下内容:

public class myClass
{
    public string myStringOne { get; set; }
    public string myStringTwo { get; set; }
    public string myStringThree { get; set; }
    public string mystringFour { get; set; }
}

并在UI.xaml下面进行控制。

<Grid HorizontalAlignment="Left" Height="239" VerticalAlignment="Top" Width="439">
    <DataGrid x:Name="PhoneGrid" VerticalAlignment="Top" Height="134"
              CanUserReorderColumns="False" 
              CanUserResizeColumns="False" 
              CanUserResizeRows="False" 
              CanUserSortColumns="False" 
              Focusable="False" 
              IsReadOnly="True"
        DataContext="{Binding RelativeSource={RelativeSource AncestorType=Window}}"
        ItemsSource="{Binding myObservable}" MouseLeftButtonUp="PhoneGrid_MouseLeftButtonUp" SelectionUnit="Cell" Margin="10,100,10,0" />

我设置 backgroundworker 的方式:

private readonly BackgroundWorker _worker = new BackgroundWorker();
private readonly object _lock = new object();
_worker.DoWork += LoadLines;
var timer = new Timer(Settings.Default.Interval);
timer.Elapsed += timer_Elapsed;
timer.Start();

LoadLines 是我执行 UI 阻止事情的功能。

我尝试实现

// Prepare obervable collection
BindingOperations.EnableCollectionSynchronization(myObservable, _lock);

以及

Dispatcher.Invoke(() => {
    myObservable[index].myString = "anyStr";
});

当我从 myObservable 中添加和删除 myClass' 时它起作用了。但是,当我更改 myClass 的 属性 时,即使 myObservable 的值已更改,更改也不会反映在 WPF DataGrid 中。

我错过了什么?

我尝试了其他几个来源,但无济于事。奇怪的是,在 UI 线程以外的线程上修改集合似乎是可能的。当 运行 在新线程上或在 UI 线程上调用它时,我无法察觉任何行为差异。

您的 myClass 需要实现 INotifyPropertyChanged。这就是 WPF 数据绑定通知 UI 属性更改的方式。

public class myClass: INotifyPropertyChanged
{
    private string _myStringOne;
    public string myStringOne { 
       get { return _myStringOne; } 
       set 
       {
           if(_myStringOne != value)
            {
                  _myStringOne = value;
                  NotifyPropertyChanged("myStringOne");
            }
      }
   }

   public event PropertyChangedEventHandler PropertyChanged;

   public void NotifyPropertyChanged(string propName)
   {
        if(this.PropertyChanged != null)
             this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
   }
}