自动更新绑定数据网格的正确方式(非丑陋方式)

本文关键字:方式 更新 绑定 数据 网格 数据网 | 更新日期: 2023-09-27 18:25:37

我正在寻找一种以"非丑陋的方式"自动更新绑定数据网格的正确方法。我有一个带有数据网格的wpf应用程序,我已经将其绑定到数据表:

MeasurementResultsDataGrid.ItemsSource = _main.CurrentMeasurement.MeasurementDataTable.AsDataView(); 

非常简单!接下来,我使用接口INotifyPropertyChanged将模型与UI:同步

    public event PropertyChangedEventHandler PropertyChanged;
    public MeasurementDataSet.MeasurementDataTable MeasurementDataTable 
    {
        get
        {
            return _measurementDataTable;
        }
        set
        {
            _measurementDataTable = value;
            NotifyPropertyChanged("MeasurementDataTable");
        } 
    }
    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

一个线程正在向数据表中添加新行,并且没有任何错误。不出所料,当线程更新表时,DataGrid不会更新/"刷新"。最好的方法是什么?我宁愿不使用单独的定时器/线程来更新数据网格:datagrid.refresh()&数据网格重新绑定。。

我在这方面搜索了很多,似乎我走在了正确的轨道上,但我错过了一些关键的部分!

自动更新绑定数据网格的正确方式(非丑陋方式)

首先不要绑定到方法的返回值,因为返回值会被复制,永远不会改变。

将ItemsSource绑定到实现INotifyPropertyChanged的类型的属性。在您的情况下,我建议使用ObservableCollection。这样做的好处是,如果存储在集合中的项正在实现INotifyPropertyChanged并被更改,则UI将在不调用refresh()rebind()的情况下更新。

您可以添加一个属性:

    public DataView  MeasurementDataTableView 
    {
        get
        {
            return MeasurementDataTable.AsDataView();
        }           
    }

然后将其用作ItemsSource(不确定这是否有效,如果无效,我认为您可以使用绑定用XAML代码设置它):

MeasurementResultsDataGrid.SetBinding(DataGrid.ItemsSourceProperty, "MeasurementDataTableView") ; 

这样您就可以在向数据表添加新行之后添加NotifyPropertyChanged("MeasurementDataTableView")

经过长时间的搜索和尝试建议的答案,我已经实现了@coder0815的答案的第二部分,并使用了Observable Collection而不是DataTable。现在我似乎不必实现INotifyCollectionChanged接口,UI会自动更新!

如果您在UI线程上创建了集合,那么只有在尝试更新集合时才要注意,WPF中大多数时候都会发生这种情况。在WPF<4.5您必须使用委托来超越"此类型的CollectionView不支持从不同于Dispatcher线程的线程更改其SourceCollection"异常。如果您的WPF>4.5,您可以使用以下内容:

在UI线程上创建一个变量,例如:

private SynchronizationContext _uiContext;

在创建UI时,初始化值:

_uiContext=SynchronizationContext.Current;

现在,您可以使用以下内容轻松更新集合:

_uiContext.Send(x=>YOUR_METHOD(),null);

用集合中的方法替换YOUR_METHOD!