我正在使用带有动态字段生成器的MVVM模型,其中字段是从数据库中提取的,这样做是因为不同类型的表单需要不同的字段(TextBox / TextBlock,ComboBox等)。问题是我正在尝试从字典中检索一个值,以便在表单的TextBlock中显示,但我不确定如何绑定检索到的Key以便我可以显示该值。
目前,我正在做以下事情:
TextBlock textBlock = new TextBlock();
textBlock.SetBinding(TextBlock.TextProperty, createFieldBinding(myPropertyName);
使用以下绑定方法:
private Binding createFieldBinding(string fieldName) {
Binding binding = new Binding(fieldName);
binding.Source = this.DataContext;
binding.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
return binding;
}
我传递的内容如Score
,映射到ViewModel中的Score
属性,但是如何绑定到Dictionary Key以检索其值?
如果可能的话,我希望能够绑定到myDictionaryProperty[myDictionaryKey]
这样的东西。
实施例:
以下为ID为1的玩家生成PlayerScore
。
PlayerScore
为Dictionary<int, int>
且PlayerID
为int
的位置。
<TextBlock Name="textBlockA" Text="{Binding PlayerScore[1]} />
答案 0 :(得分:3)
绑定到索引属性是可能的,并使用与C#相同的表示法,就像你写的那样:
<TextBlock Name="textBlockA" Text="{Binding PlayerScore[1]}" />
传递给“createFieldBinding”的字符串是属性路径。如果将源设置为字典,则只需传递索引器部分,如“[1]”,就像在xaml中完成此操作一样:
<TextBlock Name="textBlockA" Text="{Binding [1]}" />
答案 1 :(得分:3)
使用@Clemens提供的this solution,我能够根据我的Dictionary的数据类型构建自己的DictionaryItemConverter,并创建一个绑定Key
和Dictionary
在一起。
转换器:
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();
}
}
多重绑定方法:
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;
}