wpf 如何将基于 Key 的 Dictionary Value 绑定到 Code-Behind 中的 TextBlock?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13802266/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I bind Dictionary Value based on Key to a TextBlock in Code-Behind?
提问by Bob.
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.
我正在使用带有动态字段生成器的 MVVM 模型,其中字段是从数据库中提取的,这样做是因为不同类型的表单需要不同的字段(TextBox/TextBlock、ComboBox 等)。问题是我试图从字典中检索一个值,以在表单的 TextBlock 中显示,但我不确定如何绑定检索到的 Key 以便我可以显示该值。
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 Scoreproperty in the ViewModel, but how would I bind to a Dictionary Key to retrieve its Value?
我通过 like 传递一些东西Score,它映射到ScoreViewModel 中的一个属性,但是我如何绑定到字典键来检索它的值?
I want to be able to bind to something like myDictionaryProperty[myDictionaryKey], if that is possible.
myDictionaryProperty[myDictionaryKey]如果可能的话,我希望能够绑定到类似的东西。
Example:
The below generates the PlayerScorefor Player with ID of 1.
Where PlayerScoreis a Dictionary<int, int>and PlayerIDis an int.
示例:下面生成PlayerScoreID 为 1的for Player。其中PlayerScore是 aDictionary<int, int>和PlayerID是int。
<TextBlock Name="textBlockA" Text="{Binding PlayerScore[1]} />
回答by Arthur Nunes
Binding to indexed properties is possible and uses the same notation as C#, just like you wrote:
绑定到索引属性是可能的,并且使用与 C# 相同的符号,就像你写的一样:
<TextBlock Name="textBlockA" Text="{Binding PlayerScore[1]}" />
The string you pass to "createFieldBinding" is the property path. If you set the source as the dictionary, you just need to pass the indexer part, like "[1]", as if you had done like this in xaml:
您传递给“createFieldBinding”的字符串是属性路径。如果将源设置为字典,则只需要传递索引器部分,例如“[ 1]”,就好像您在 xaml 中这样做一样:
<TextBlock Name="textBlockA" Text="{Binding [1]}" />
回答by Bob.
Using this solutionprovided 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 Keyand the Dictionarytogether.
使用@Clemens 提供的这个解决方案,我能够基于我的 Dictionary 的数据类型构建我自己的 DictionaryItemConverter,并创建一个将 theKey和 the绑定Dictionary在一起的多绑定方法。
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;
}

