繁体   English   中英

数据绑定+ DataGrid - 如何连接?

[英]Databinding + DataGrid - how to connect?

这个问题是我之前的问题DataGrid的结果- 当新数据到达时,网格选择被重置

================================================== ===================

我有这样的DataGrid

<DataGrid AutoGenerateColumns="True" HorizontalAlignment="Stretch" Name="dataGrid1" VerticalAlignment="Stretch" ItemsSource="{Binding DataList}" IsReadOnly="True"/>

在我的ViewModel中我有这样的字段:

public ObservableCollection<ConsoleData> DataList { get; set; }

这种方法每秒调用一次:

private void model_DataArrived(List<ConsoleData> dataList)
{
    DataList.Clear();
    dataList.ForEach(x => DataList.Add(x));
}

================================================== ===================

我们已经发现,因为我调用了DataList.Clear ,所以UI控件中的选择也被清除了,我不希望这种情况发生。 因此,我不应该在ViewModel替换ConsoleData实例,而应该update这些实例。

ObservableCollection注意到添加/删除我猜并没有观察update是不是? 那么,如果我将update实例DataBinding将无法正常工作?

当前应用程序的另一个问题是dataList.ForEach(x => DataList.Add(x)); 强制数据绑定在每次迭代时执行而不是仅在结束时执行?

总的来说,做我想做的事情的正确方法是什么,因为当前的应用程序不起作用并且有太多问题......

目前尚不清楚您计划如何更新ObservableCollection的项目。 至少有两种方法可以做到这一点。 一种方法是更新ConsoleData对象中更改的所有属性。 在这种情况下,您将使用ConsoleData实现INotifyPropertyChanged 另一种方法是直接更新ObservableCollection的item。 为此,您可以使用ObservableCollectionSetItem方法。 这将引发CollectionChanged事件, 因为SetItemMSDN文档指示。

由于您已经表明您正在使用MVVM,因此通常接受的做法是使您的ObservableCollection成为ConsoleDataViewModel的集合而不是ConsoleData。

当前应用程序的另一个问题是dataList.ForEach(x => DataList.Add(x)); 强制数据绑定在每次迭代时执行而不是仅在结束时执行?

如果你修改你的model_DataArrived方法来更新而不是如上所示的clear / add,我认为你不会遇到刷新问题。

问题是ObservableCollection在项目更改时没有通知; 正如您所说,它仅在添加和删除项目时通知。 为了解决这个问题,我创建了一个名为VeryObservableCollection的类。 对于添加的每个对象,它将对象的NotifyPropertyChanged事件挂钩到触发CollectionChanged事件的处理程序。 对于删除的每个对象,它将删除处理程序。 很简单,应该解决你的问题。 您只需要确保在集合中保存的对象上实现NotifyPropertyChanged。 例如:

public class VeryObservableCollection<T> : ObservableCollection<T>

/// <summary>
/// Override for setting item
/// </summary>
/// <param name="index">Index</param>
/// <param name="item">Item</param>
protected override void SetItem(int index, T item)
{
    try
    {
        INotifyPropertyChanged propOld = Items[index] as INotifyPropertyChanged;
        if (propOld != null)
            propOld.PropertyChanged -= new PropertyChangedEventHandler(Affecting_PropertyChanged);
    }
    catch (Exception ex)
    {
        Exception ex2 = ex.InnerException;
    }
    INotifyPropertyChanged propNew = item as INotifyPropertyChanged;
    if (propNew != null)
        propNew.PropertyChanged += new PropertyChangedEventHandler(Affecting_PropertyChanged);

    base.SetItem(index, item);
}

我想你可以做这样的事情

private ObservableCollection<ConsoleData> dataList;
public ObservableCollection<ConsoleData> DataList 
{ 
   get {return dataList; } 
   set {dataList = value;} 
}

并且您的数据操作只访问字段dataList 一次完成操作强制DataBinding更新或重新分配它,以这种方式强制Biding向WPF发出通知。

应该工作。

如果你的ConsoleData实现了INotifyPropertyChanged,你可以简单地更新这些,你会看到你的ui中的变化 - 没有选择丢失。

好的,首先我们需要了解一个项目,它是任何Selector控件(如ListBoxDataGrid等)上的Selector源,如果删除,将会松散选择。

为此,请使用批量添加和单一通知FastObservableCollection

但是为了保持这样的选择,一旦ClearAddRange发生,你将不得不将所选的项目/值设置回DataGrid

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM