I have a combobox's itemSource
property bound to a property of type Dictionary<string,List<string>>
. This is so I do not need to create a large amount of properties in my datacontext file. For example, I have 2 ComboBoxes (CoBoA, CoBoB), and i have a dict
private Dictionary<string, List<string>> _itemSources = new Dictionary<string, List<string>>()
{
{"CoBoA", new List<string>() }, {"CoBoB", new List<string>() }
};
public Dictionary<string, List<string>> ItemSources
{
get
{
return _itemSources ;
}
set
{
_itemSources = value;
OnPropertyChanged(nameof(ItemSources));
}
}
// initialise populate itemSources in constructor or elsewhere
<!-- CoBoA -->
<ComboBox IsEditable="True"
ItemsSource="{Binding ItemSources[CoBoA]}"/>
<!-- CoBoB -->
<ComboBox IsEditable="True"
ItemsSource="{Binding ItemSources[CoBoB]}"/>
When you open the ComboBox, any new items added to the List<string> value in the dictionary (after opening the ComboBox) will not show up - though OnPropertyChanged() was called. However, if you add items to the List<string> value before you open the ComboBox, they'll show up.
I put breakpoints on the setter and theyre never triggered. This may be wrong, but I believe this also occurs on List<T>
s. Because of this, I tried to call OnPropertyChanged(nameof(<PropertyName>))
when I update the dict with new values for the List<string>
key. That didn't work. I'd get the same behaviour as before.
Incase it's important, I update the dict like so
ItemSources[key].Add(value);
Any help would be greatly appreciated. I can provide more info about my specific solution if need be.
So, are you want to update the items of ComboBox
when the List<string>
changes?
You should use ObservableCollection
not List
. ObservableCollection
can notify the items changes to Binding target.
And INotifyPropertyChanged
implementation is notifies that "this property's reference or value has changed", not that "the instance of this property has changed".
So you update dictioanry items will not notify anything. If you need notify the dictionary inner changes to binding target after shown, see Ferid's answer.
Otherwise, if the ComboBox are static binding to existed dictionary item, you just need a simple auto property, and set Mode=OneTime
on Binding
(ItemsSource="{Binding ItemSources[CoBoA], Mode=OneTime}"
) to avoid potential memory leak issues.