【问题标题】:Async modification of ObservableCollection<T> not represented in DataGrid异步修改 ObservableCollection<T> 未在 DataGrid 中表示
【发布时间】:2016-02-22 15:16:00
【问题描述】:

自从我使用 Forms/WPF 以来已经有一段时间了。如果这是一个愚蠢的问题,请原谅。

我有一个名为myObservableObservableCollection&lt;myClass&gt;,其中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 的属性时,即使 myObservable 的值已更改,更改也不会反映在 WPF DataGrid 中。

我错过了什么?

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

【问题讨论】:

    标签: c# wpf multithreading datagrid observablecollection


    【解决方案1】:

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

    【讨论】:

    • 谢谢@Steve Wong,就是这样。我的事情已经开始了。
    猜你喜欢
    • 2021-08-25
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 2014-11-05
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 2011-11-24
    相关资源
    最近更新 更多