I have a class with a property Errors
defined as:
public MultiLookup<string, Exception> Errors { get; private set; }
MultiLookup is of type ILookup as defined:
public class MultiLookup<TKey, TValue,TCollection> : ILookup<TKey, TValue>
This is bound to the ItemsSource property of an ItemsControl defined in XAML:
<ItemsControl ItemsSource="{Binding Path=Errors}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Label Content="{Binding Path=Key}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
No items are rendered
Inspecting the live property explorer one can see that there are no items in the control being rendered. The stack panel should have 4 items in it.
However there are 4 keys in the lookup table as shown in the live property explorer within Visual Studio, during a debug session.
Why do the 4 items not get rendered?
There are two reasons here.
Items.Refresh
on the ItemsControl
the binding does not update the ItemsControl. The solution is simple. Create an immutable version of the collection that I update on every change.
private readonly MultiLookup<string, Exception, List<Exception>>
_Errors;
[Reactive]public ILookup<string, Exception> Errors
{ get; private set; }
where _Errors
is the mutable version for internal handling and Errors
is the immutable version which raises INPC
events. I'm using ReactiveUI.Fody
to implement INPC
On every change to the mutable version I just call
// 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);
It now updates the ItemsControl correctly.
I could also have implemented MultiLookup with INotifyCollectionChanged
to get a similar effect. Given that the expected size of this collection will always be very small ( less than 10 ) there is little overhead in generating a new copy each time. INotifyCollectionChanged` is also quite complex to get working correctly for a data structure like a lookup.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.