ObservableCollection在DataGrid中未表示

本文关键字:DataGrid 未表示 修改 异步 ObservableCollection | 更新日期: 2023-09-27 18:35:45

我已经有一段时间没有使用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" />

我设置后台工作者的方式:

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 属性时,更改不会反映在 WPF 数据网格中,即使myObservable其值已更改也是如此。

我错过了什么?

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

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

你的 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));
   }
}