Report that a specific value has changed in the dictionary

I am currently writing my own dictionary that implements INotifyPropertyChanged . See below:

public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } new public Item this[TKey key] { get { return base.Item[key]; } set(TValue value) { if (base.Item[key] != value) { base.Item[key] = value; OnPropertyChanged("XXX"); // what string should I use? } } } 

My goal is simple: when a certain meaning in a dictionary has changed, let it know that it has changed. All WPF elements that are bound to the corresponding key name must then be updated.

Now my question is: which line should I use as propertyName to notify?

I tried "[" + key.ToString() + "]" , "Item[" + key.ToString() + "]" and just key.ToString() . All of them did not seem to work because WPF elements were not updated.

Using String.Empty ( "" ) updates the WPF elements, but I do not use it because it will update all WPF elements that are connected by the same dictionary, even if they have different keys.


This is how my binding looks in XAML:

 <TextBlock DataContext="{Binding Dictionary}" Text="{Binding [Index]}" /> 

Index is, of course, the key name in my dictionary.


Instead of using INotifyPropertyChanged, some suggested using INotifyCollectionChanged . I tried this:

 Dim index As Integer = MyBase.Keys.ToList().IndexOf(key) Dim changedItem As Object = MyBase.ToList().ElementAt(index) RaiseEvent CollectionChanged(Me, New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, changedItem, index)) 

But it also does not update related WPF elements.

+4
source share
2 answers

You might need to consider INotifyCollectionChanged rather than INotifyPropertyChanged . If this is the case, check out this question and the blog post to which it refers.

Also, check this answer to a previous question that was similar to yours. This assumes that you are using the value of Binding.IndexerName as the property name for change notification.

Edit:

If you want to avoid using INotifyCollectionChanged , you can try an alternative approach. Modify the dictionary so that its value type is a proxy object that implements INotifyPropertyChanged .

 public class MyProxy<T> : INotifyPropertyChanged { public T Value { // Getter and setter with change notification code here. } } 

Then insert instances of this type in your dictionary only once. Replace the code that updates the value in the dictionary with the code that the proxy server retrieves and then updates its Value property.

You will need to change the XAML binding to something like ([Item]).Value .

After looking at some of your other comments, it looks like this approach may work for you. This is similar to what I had to do recently. Create your own KeyedCollection and corresponding proxy. Add the ItemName property to the proxy; it may be read-only and does not need support for change notifications. Add your KeyedCollection implementation index to the KeyedCollection property. Works! If you want, I will add sample code.

+6
source
 if (base.Item[key] != value) { base.Item[key] = value; if (key == "notifykey") OnPropertyChanged("[Item]"); } 

String.empty will notify all properties of not only Item

In this case, the problem of all dictionary bindings is still updated.
So I would make a new property

Assume value is equal to the string Bind to KeyedValue

 public String KeyedValue { get { return base.Item[Index]; } } if (key == "Index") OnPropertyChanged("KeyedValue"); 
0
source

All Articles