在Silverlight中,当项目被添加到ObservableCollection中时,DataGrid不更新
本文关键字:中时 ObservableCollection DataGrid 更新 Silverlight 项目 添加 | 更新日期: 2023-09-27 18:05:53
我有一个与WCF服务交互的Silverlight应用程序。它定期从该服务接收要添加到列表中的新项,并将每个新元素添加到ObservableCollection(每个新元素的collection.Add())的末尾。
项目本身不改变一旦他们被接收,项目的类继承INotifyPropertyChanged,但是当我添加新的项目(从WCF接收),DataGrid不更新。
我还为DataGrid绑定使用了自定义格式化程序,但我不认为这是一个问题,因为初始项集正确显示(当ItemsSource第一次设置时)。
我希望出现新元素,因为我已经确认ObservableCollection正在发出正确的add事件。因为ObservableCollection继承自INotifyCollectionChanged,它不应该更新数据网格吗?
到目前为止我找到的唯一解决方案是:
dataGrid.ItemsSource = null;
dataGrid.ItemsSource = collection;
有什么办法让它更新吗?这个方法会阻塞UI很长一段时间。
由于
更新:代码
在WCF回调事件中展开和提取元素:
// The ItemWrapper allows the Binding converter to be passed the entire trade object, rather than just each property.
ObservableCollection<ItemWrapper<ExpandedTrade>> pastTrades = new ObservableCollection<ItemWrapper<ExpandedTrade>>();
....
// Extract and expand data - MinimalTrade is the data sent through WCF
var convertedTrades = from MinimalTrade t in e.trades
select new ItemWrapper<ExpandedTrade>(
new ExpandedTrade(t,
usernames.ContainsKey(t.UserToId) ? usernames[t.UserToId] : null, potentialWealth != null ? potentialWealth.CurrentWealth : null)); // Get name, otherwise null.
// Data now expanded (to show full information like usernames
// pastTrades is an observableCollection
foreach (var trade in convertedTrades)
{
pastTrades.Add(trade);
}
OnNewMyTradeHistory(pastTrades);
OnNewMyTradeHistory事件然后这样做:
if (tradeHistory.ItemsSource == null) tradeHistory.ItemsSource = trades;
这只设置ItemsSource一次(到ObservableCollection),并且add事件正在触发,但是UI端没有发生任何事情。
WCF回调可能发生在另一个线程中。
我找到解决方案了!
我已经在ItemWrapper和expdedtrade中实现了Equals
, GetHashCode
和ToString
方法:
ItemWrapper.cs:(调用子类中的等效方法)
public override bool Equals(object obj)
{
if(obj is T) return Quote.Equals(obj);
if (obj is ItemWrapper<T>) return Quote.Equals(((ItemWrapper<T>)obj).Quote);
return this == obj;
}
public override int GetHashCode() { return Quote.GetHashCode(); }
public override string ToString() { return Quote.ToString(); }
ExpandedTrade.cs:
public override bool Equals(object obj)
{
if (obj == null) return false;
ExpandedQuote q = obj as ExpandedQuote;
if (q == null) return false;
return q.Id == Id;
}
public override int GetHashCode() { return Id; }
删除这些方法后,它工作了。我想象DataGrid在某处测试相等性,不知怎的,有些东西返回了一个不正确的测试。id是唯一的,但是通过使用默认的引用相等性测试,它现在可以工作了。
告诉我这个流程是否正确:
- DataGrid。
- (更新)
- 创建新的可观察对象collection: CollectionA
- 获取物品并添加到CollectionA
- (事件)
- DataGrid。ItemsSource == null -> ItemsSource = CollectionA
- (更新)
- 创建新的可观察对象集合:CollectionB
- 获取项目并添加到CollectionB
- (事件)
- DataGrid。ItemsSource != null ->不做任何事
- => DataGrid。ItemsSource == CollectionA?
或者pastTrades是一个只初始化一次的字段?括号和方法边界会有帮助。