繁体   English   中英

为什么我的ItemsControl不呈现ILookup <T,V> 设置为ItemsSource时

[英]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个项目无法渲染?

这里有两个原因。

  1. 我的MultiLookup没有实现INotifyCollectionChanged。
  2. 即使您在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM