[英]Why is my ItemsControl not render ILookup<T,V> when set as ItemsSource
我有一个类,其属性Errors
定义为:
public MultiLookup<string, Exception> Errors { get; private set; }
MultiLookup的类型为ILookup ,定义如下:
public class MultiLookup<TKey, TValue,TCollection> : ILookup<TKey, TValue>
这绑定到XAML中定义的ItemsControl的ItemsSource属性:
<ItemsControl ItemsSource="{Binding Path=Errors}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Label Content="{Binding Path=Key}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
没有项目呈现
检查活动属性浏览器后,可以看到控件中没有正在渲染的项目。 堆栈面板中应包含4个项目。
但是,在调试会话期间,查找表中有4个键,如Visual Studio的实时属性浏览器中所示。
为什么4个项目无法渲染?
这里有两个原因。
ItemsControl
上手动调用Items.Refresh
,绑定也不会更新ItemsControl。 解决方案很简单。 创建该集合的不变版本,我会在每次更改时对其进行更新。
private readonly MultiLookup<string, Exception, List<Exception>>
_Errors;
[Reactive]public ILookup<string, Exception> Errors
{ get; private set; }
其中_Errors
是内部处理的可变版本,而Errors
是引发INPC
事件的不可变版本。 我正在使用ReactiveUI.Fody
实现INPC
在对可变版本进行的每次更改中,我都称之为
// Create a new immutable lookup on every error change.
Errors = _Errors
.SelectMany(p => p.Select(i => new {p.Key, i}))
.ToLookup(o => o.Key, o => o.i);
现在,它可以正确更新ItemsControl。
我还可以使用INotifyCollectionChanged
实现MultiLookup以获得类似的效果。 鉴于此集合的预期大小将始终很小(小于10),因此每次生成新副本的开销很少。 INotifyCollectionChanged`对于要像查找这样的数据结构正确工作也非常复杂。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.