Reputation: 3338
I have a dictionary of items and I would like to show an aspect of items in a combobox - all in a MVVM pattern. In this regard, I define my Model
as:
public class Model
{
public Dictionary<UInt32, string> samples { set; get; }
}
and my ViewModel
as:
internal class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
var smpls = new Dictionary<UInt32, string>();
smpls.Add(1, "one");
smpls.Add(2, "two");
models = new Dictionary<string, Model>();
models.Add("aKey", new Model() { samples = smpls });
key = "aKey";
}
private Dictionary<string, Model> _models;
public Dictionary<string, Model> models { set { _models = value; } get { return _models; } }
private string _key;
public string key { set { _key = value; OnPropertyChanged("key"); } get { return _key; } }
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
Then I bind models
to a combobox as:
<Grid>
<ComboBox ItemsSource="{Binding Path=models[{Binding Path=key}].samples, Mode=OneTime}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Border>
<StackPanel>
<TextBlock Text="{Binding Path=Value}" />
</StackPanel>
</Border>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
I'm binding the Key of models
dictionary to key
property of viewModel
which does not work. However, if I change the code as following everything works fine:
<ComboBox ItemsSource="{Binding Path=models[aKey].samples, Mode=OneTime}">
Upvotes: 3
Views: 4733
Reputation: 128157
While models[aKey].samples
is a valid property path, models[{Binding Path=key}].samples
isn't. You might probably get around this limitation by using a MultiBinding with a appropriate value converter.
It would however by much easier to create an additional view model property like the CurrentSamples
property shown below, which is updated whenever the key
property changes:
public Dictionary<UInt32, string> CurrentSamples
{
get { return models[key].samples; }
}
public string key
{
get { return _key; }
set
{
_key = value;
OnPropertyChanged("key");
OnPropertyChanged("CurrentSamples");
}
}
Then bind the ItemsSource like this:
<ComboBox ItemsSource="{Binding CurrentSamples}">
...
</ComboBox>
Upvotes: 3
Reputation: 31721
I'm binding the Key of models dictionary to key property of viewModel which does not work.
Binding works by reflecting into a CLR structure. It uses the literal in the Path
attribute to find, usually, a property on a CLR instance. The models[{Binding Path=key}]
is not a proper path into a structure.
It isn't programmed to search for a binding in a binding; it takes the text as a literal for the path.
To quote MSDN Binding Sources Overview: For CLR properties, data binding works as long as the binding engine is able to access the binding source property using reflection.
So the second binding (Path=models[aKey].samples
) works because you have provided a true pathed location to reflect off of and bind to.
Upvotes: 1