当项目添加到 Silverlight 中的 ObservableCollection 时,DataGrid 不更新
我有一个与 WCF 服务交互的 Silverlight 应用程序。它定期从该服务接收要添加到列表中的新项目,并且每个新元素都会添加到 ObservableCollection 的末尾(每个新元素的 collection.Add() )。
项目本身在收到后就不会更改,并且项目的类继承 INotifyPropertyChanged,但是当我添加新项目(从 WCF 接收)时,DataGrid 不会更新。
我还为 DataGrid 绑定使用自定义格式化程序,但我认为这不是问题,因为初始项目集显示正确(首次设置 ItemsSource 时)。
我本来希望出现新元素,因为我已经确认 ObservableCollection 正在发出正确的添加事件。既然ObservableCollection继承自INotifyCollectionChanged,那么它不应该更新DataGrid吗?
到目前为止我找到的唯一解决方案是:
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)并且添加事件正在触发,但 UI 端没有任何反应。
WCF 回调可能发生在另一个线程中。
I have a Silverlight application which interacts with a WCF service. It periodically receives new items to add to a list from this service, and each new element is added to the end of an ObservableCollection (collection.Add() for each new element).
The items themselves don't change once they are received, and the items' class inherits INotifyPropertyChanged, however when I add new items (received from WCF), the DataGrid doesn't update.
I am also using a custom formatter for the DataGrid binding, but I don't think this is a problem as the initial set of items appear correctly (when the ItemsSource is first set).
I would have expected the new elements to appear, as I have confirmed that the ObservableCollection is emitting the correct add event. Since ObservableCollection inherits from INotifyCollectionChanged, shouldn't it update the DataGrid?
The only solution I have found so far is:
dataGrid.ItemsSource = null;
dataGrid.ItemsSource = collection;
Any ideas on how to get it updating? This method blocks the UI for a noticable amount of time.
Thanks
UPDATE: Code
The elements are expanded and extracted in the WCF callback event:
// 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);
The OnNewMyTradeHistory event then does this:
if (tradeHistory.ItemsSource == null) tradeHistory.ItemsSource = trades;
This only sets ItemsSource once (to the ObservableCollection) and the add events are firing, but nothing is happening on the UI side.
The WCF callbacks might be happening in another thread.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我找到了解决方案!
我已经在 ItemWrapper 和 ExpandedTrade 中实现了
Equals
、GetHashCode
和ToString
方法:ItemWrapper.cs:(调用子类中的等效方法)
ExpandedTrade.cs:
删除这些方法后,它起作用了。我想象 DataGrid 正在某处测试相等性,并且不知何故某些东西返回了错误的测试。 ID 是唯一的,但通过使用默认的引用相等测试,它现在可以工作。
I found the solution!
I had implemented the
Equals
,GetHashCode
andToString
methods in both ItemWrapper and ExpandedTrade:ItemWrapper.cs: (Calls the equivalent methods in the child class)
ExpandedTrade.cs:
After removing these methods, it worked. I'd imagine that the DataGrid was testing for equality somewhere, and somehow something was returning an incorrect test. The IDs are unique, but by using the default test of equality by reference, it now works.
告诉我这个流程是否正确:
或者 PastTrades 是一个只初始化一次的字段吗?括号和方法边界会有所帮助。
Tell me if this flow is correct:
Or is pastTrades a field which is only initialized once? Brackets and method boundaries would help.