数据绑定+数据网格-如何连接
本文关键字:何连接 连接 数据 数据网 网格 数据绑定 | 更新日期: 2023-09-27 18:15:31
这个问题是我之前的问题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。为此,可以使用ObservableCollection
的SetItem
方法。这将引发CollectionChanged
事件,正如SetItem
的MSDN文档所指示的那样。
既然你已经表明你正在使用MVVM,一般接受的事情是让你的ObservableCollection
是ConsoleDataViewModel的集合,而不是ConsoleData。
当前应用程序的另一个问题是
dataList.ForEach(x => DataList.Add(x));
强制数据绑定在每次迭代上执行,而不是只在最后执行?
我不认为你会有刷新问题,如果你修改你的model_DataArrived方法更新,而不是清除/添加,如上所述。
问题是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
控件(如ListBox
, DataGrid
等)上作为选择源的项,如果被删除,将失去选择。
为此,请使用批量添加和单个通知FastObservableCollection。
但是为了保持这样的选择,一旦出现Clear
和AddRange
,您必须将选中的项/值设置回DataGrid
。