I am using the MVVM model with a dynamic field generator, where the field is pulled from the database, done this way because different types of forms require different fields (TextBox/TextBlock, ComboBox, etc.). The problem is I'm trying to retrieve a value from a dictionary, to display in a TextBlock for the form, but I'm not sure how to bind the retrieved Key so I can display the value.
Currently, I am doing the following:
TextBlock textBlock = new TextBlock();
textBlock.SetBinding(TextBlock.TextProperty, createFieldBinding(myPropertyName);
With the following binding method:
private Binding createFieldBinding(string fieldName) {
Binding binding = new Binding(fieldName);
binding.Source = this.DataContext;
binding.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
return binding;
}
Where I pass something through like Score
, which maps to a Score
property in the ViewModel, but how would I bind to a Dictionary Key to retrieve its Value?
I want to be able to bind to something like myDictionaryProperty[myDictionaryKey]
, if that is possible.
Example:
The below generates the PlayerScore
for Player with ID of 1.
Where PlayerScore
is a Dictionary<int, int>
and PlayerID
is an int
.
<TextBlock Name="textBlockA" Text="{Binding PlayerScore[1]} />
Using this solution provided by @Clemens, I was able to build my own DictionaryItemConverter, based on the data types for my Dictionary, and create a multi-binding method that would bind the Key
and the Dictionary
together.
Converter:
public class DictionaryItemConverter : IMultiValueConverter {
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
if(values != null && values.Length >= 2) {
var myDict = values[0] as IDictionary;
if(values[1] is string) {
var myKey = values[1] as string;
if(myDict != null && myKey != null) {
//the automatic conversion from Uri to string doesn't work
//return myDict[myKey];
return myDict[myKey].ToString();
}
}
else {
long? myKey = values[1] as long?;
if(myDict != null && myKey != null) {
//the automatic conversion from Uri to string doesn't work
//return myDict[myKey];
return myDict[myKey].ToString();
}
}
}
return Binding.DoNothing;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) {
throw new NotSupportedException();
}
}
Multi-Bind Method:
private MultiBinding createFieldMultiBinding(string fieldName) {
// Create the multi-binding
MultiBinding mbBinding = new MultiBinding();
// Create the dictionary binding
Binding bDictionary = new Binding(fieldName + "List");
bDictionary.Source = this.DataContext;
// Create the key binding
Binding bKey = new Binding(fieldName);
bKey.Source = this.DataContext;
// Set the multi-binding converter
mbBinding.Converter = new DictionaryItemConverter();
// Add the bindings to the multi-binding
mbBinding.Bindings.Add(bDictionary);
mbBinding.Bindings.Add(bKey);
return mbBinding;
}