[英]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。 為此,您可以使用ObservableCollection
的SetItem
方法。 這將引發CollectionChanged
事件, 因為SetItem
的MSDN文檔指示。
由於您已經表明您正在使用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
控件(如ListBox
, DataGrid
等)上的Selector
源,如果刪除,將會松散選擇。
為此,請使用批量添加和單一通知FastObservableCollection 。
但是為了保持這樣的選擇,一旦Clear
和AddRange
發生,你將不得不將所選的項目/值設置回DataGrid
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.