簡體   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