【问题标题】:How do I bind Dictionary Value based on Key to a TextBlock in Code-Behind?如何在代码隐藏中将基于键的字典值绑定到 TextBlock?
【发布时间】:2012-11-27 22:39:24
【问题描述】:

我正在使用带有动态字段生成器的 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 属性,但我如何绑定到字典键以检索其值?

如果可能的话,我希望能够绑定到 myDictionaryProperty[myDictionaryKey] 之类的东西。

示例: 下面为 ID 为 1 的玩家生成PlayerScore。 其中PlayerScore 是Dictionary<int, int>,PlayerID 是int。

 <TextBlock Name="textBlockA" Text="{Binding PlayerScore[1]} />

【问题讨论】:

  • 您必须创建一个MultiBinding,正如今天对this question 的回答中所解释的那样。
  • 我不知道 MVVM。我只是使用 Source 到 Dictionary 和 Path = Value
  • @Clemens 太棒了,谢谢!我花了一些时间来修补我想要的东西,但这个解决方案对我有用。

标签: c# wpf binding dictionary code-behind


【解决方案1】:

可以绑定到索引属性,并且使用与 C# 相同的符号,就像您写的那样:

<TextBlock Name="textBlockA" Text="{Binding PlayerScore[1]}" />

您传递给“createFieldBinding”的字符串是属性路径。如果将源设置为字典,则只需传递索引器部分,例如“[1]”,就好像您在 xaml 中这样做过一样:

<TextBlock Name="textBlockA" Text="{Binding [1]}" />

See this

【讨论】:

  • 如果1 是一个属性呢?
  • 如果您正确设置了源并希望绑定到名为“1”的属性,只需使用“{Binding 1}”即可。如果“1”是索引返回的对象的属性,那么您只需将其附加到路径“{Binding [MyIndex].1}”(假设绑定源是字典或实现索引器的对象)。请注意,在 C# 中,标识符不能以数字字符 msdn.microsoft.com/en-us/library/aa664670.aspx 开头
【解决方案2】:

使用@Clemens 提供的this solution,我能够根据我的字典数据类型构建我自己的 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;
 }

【讨论】:

    猜你喜欢
    • 2014-11-08
    • 1970-01-01
    • 2010-12-16
    • 2012-07-15
    • 2020-02-08
    • 2019-07-06
    • 2011-04-09
    • 2010-11-19
    • 1970-01-01
    相关资源
    最近更新 更多