Bind observable dictionary

I wrote a little observable dictionary and I want to bind it to a ComboBox and a ListBox.

Indeed, it does not work and I do not know why.

This is my ObservableDictionary wrapper class (I did some experiments and raised some events in Add()):

Code Snippet

public class ObservableDictionary<TKey, TValue> : INotifyPropertyChanged, INotifyCollectionChanged, IDictionary<TKey, TValue>

{
private Dictionary<TKey, TValue> _dic = new Dictionary<TKey, TValue>();

public event PropertyChangedEventHandler PropertyChanged;
public event NotifyCollectionChangedEventHandler CollectionChanged;

private void OnCollectionChanged( object sender, NotifyCollectionChangedAction action, object value )
{
if (CollectionChanged != null)
{
CollectionChanged( sender, new NotifyCollectionChangedEventArgs( action, value ) );
}
}

private void OnPropertyChanged( object sender, string propertyName )
{
if (PropertyChanged != null)
{
PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
}
}


#region IDictionary<TKey,TValue> Members

public void Add( TKey key, TValue value )
{
_dic.Add( key, value );
OnCollectionChanged( this, NotifyCollectionChangedAction.Add, new KeyValuePair<TKey, TValue>(key, value) );

OnPropertyChanged( this, "Values" );
OnPropertyChanged( this, "Keys" );
OnPropertyChanged( this, "Count" );
}

...

}

My Window class:

Code Snippet

public partial class Window1 : System.Windows.Window
{
private ObservableDictionary<string, string> _layer = new ObservableDictionary<string, string>();
// save number of insertion
private int count = 0;

public Window1()
{
InitializeComponent();
}

private void OnWindowLoaded( object sender, RoutedEventArgs args )
{
// Binding configuration
Binding binding = new Binding();
binding.Source = _layer;
//binding.Path = new PropertyPath("Values" ); <-- does not work
binding.Mode = BindingMode.OneWay;
binding.NotifyOnTargetUpdated = true;
binding.NotifyOnSourceUpdated = true;

// Set binding for ComboBox
_comboBox.SetBinding( ComboBox.ItemsSourceProperty, binding );


_listBox.SetBinding( ListBox.ItemsSourceProperty, binding );
//_listBox.ItemsSource = _layer;

}

private void InsertLayer( object sender, RoutedEventArgs args )
{
// Insert values in observable collection again
try
{
_layer.Add( count.ToString(), "layer_" + count.ToString() );
count++;
}
catch (Exception e)
{
Debug.WriteLine( e.Message );
}
}

}

However, I get the collection of the dictionary and [0, layer0], [1, layer1], etc is shown, but I want to display the value only.

Can somebody help me? Setting Binding.Path to "Values" did not help.

One more question: What is the difference between SetBinding(ItemsSourceProperty, Binding) and setting the property IntemsSource?

Thanks a lot,

Alex

[4064 byte] By [alex_ger] at [2008-1-9]
# 1

WPF binding doesn't presently support indexing by anything except integer. A work around is to build a dictionary binding adapter, which implements ICustomTypeDescriptor and presents the dictionary entries as properties.

-Nate

NathanAllan at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 2

When binding to an observable dictionary, you are binding to a collection of KeyValuePair objects. You must access the Value through a binding in your item template:

Code Snippet

<ComboBox ItemsSource="{Binding Source={StaticResource MyObservableDictionary}}"

SelectedValuePath="Key">

<ComboBox.ItemTemplate>

<DataTemplate>

<TextBlock Text="{Binding Path=Value}" />

</DataTemplate>

</ComboBox.ItemTemplate>

</ComboBox>

> One more question: What is the difference between

> SetBinding(ItemsSourceProperty, Binding) and setting

> the property ItemsSource?

In the first case, the ItemsSource property is established via a binding. This approach is commonly used in markup to bind to collections dynamically. In the latter case, you are setting the property directly so the collection you supply is static. This approach is sometimes used in code.

In both cases, the collection is still monitored for changes (assuming it is observable) and works as expected.

Dr.WPF at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 3
alex_ger - do you have the full source of your ObservableDictionary? I am in need of the same thing and was about to write it... could save me some time... thanks!
DiamonDogX at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 4

To truly be observable (in the sense that the framework will be able to bind to your dictionary the same way it binds to an observable collection), you must implement more than just IDictionary, INotifyPropertyChanged, and INotifyCollectionChanged. You should read through my replies in this post.

If you don't add the collection-like behaviors, the framework will not properly bind to your dictionary and you will see problems (usually when adding or removing entries).

I have written several flavors of observable dictionaries in the past, but always under contract, so I cannot use/share those implementations here. If there is enough demand, I could re-implement an example from scratch and post it on my site.

You should be aware up front that the biggest problem with an observable dictionary is performance. Dictionaries are built for access speed. When you impose the behaviors of an observable collection on a dictionary (so that the framework can bind to it), you add overhead.

The benefit, of course, is that you can access the observable dictionary in code the same way you access any other dictionary.

As long as you are willing to accept the perf hit in both the dictionary and the binding thereof, then an observable dictionary might be appropriate for your scenario.

Dr.WPF at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 5
An example would be helpful, especially since you've done one before Smile. Would save a lot of grunt work... thanks for your replies.
DiamonDogX at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 6

I've now posted an Observable Dictionary Sample for anyone who might be interested.

Dr.WPF at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 7
Super!
DiamonDogX at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...

Visual Studio Orcas

Site Classified