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

时间:2011-11-22 21:31:48

标签: c# wpf data-binding mvvm

这个问题是我之前提问的结果DataGrid - grid selection is reset when new Data is arrived

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

我有这样的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控件中的选择也被清除了,我不希望这种情况发生。因此,我不应该在ConsoleData中替换ViewModel的实例,而应该update这些实例。ObservableCollection

update注意添加/删除我猜并且没有观察到update不是吗?那么,如果DataBinding实例dataList.ForEach(x => DataList.Add(x));不起作用?

当前应用程序的另一个问题是{{1}}强制数据绑定在每次迭代时执行而不是仅在结束时执行?

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

5 个答案:

答案 0 :(得分:1)

目前尚不清楚您计划如何更新ObservableCollection中的项目。至少有两种方法可以做到这一点。一种方法是更新ConsoleData对象中更改的所有属性。在这种情况下,您将拥有ConsoleData实现INotifyPropertyChanged。另一种方法是直接更新ObservableCollection中的项目。为此,您可以使用SetItem的{​​{1}}方法。这会引发MSDN documentation for SetItem指示的ObservableCollection事件。

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

  

当前应用程序的另一个问题是ObservableCollection强制数据绑定在每次迭代时执行而不是仅在结束时执行?

如果您修改model_DataArrived方法而不是上面指出的clear / add,我认为您不会遇到刷新问题。

答案 1 :(得分:1)

问题是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);
}

答案 2 :(得分:0)

我认为你可以做这样的事情

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

您的数据操作只能访问字段dataList。一次成功操纵部队DataBinding更新或重新分配,以此方式强制Biding向WPF发出通知。

应该工作。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

好的,首先我们需要了解在Selector控件(例如ListBoxDataGrid等)上作为选择来源的项目,如果删除,将会松开选择范围。

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

但要保留此类选择,您必须在DataGridClear发生后将所选项目/值设置回AddRange

相关问题