2012-12-10 41 views
2

我正在使用带动态字段生成器的MVVM模型,其中字段从数据库中拉出,这样做是因为不同类型的表单需要不同的字段(TextBox/TextBlock,ComboBox等)。问题是我试图从字典中检索一个值,以在TextBlock中显示表单,但我不知道如何绑定检索到的键,以便显示值。如何在代码背后将基于密钥的字典值绑定到TextBlock?

目前,我做了以下内容:

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的东西,它映射到一个Score财产视图模型,但我如何绑定到一个字典键来检索它的值?

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

实施例: 的下面的1 ID生成PlayerScore为播放器在哪里PlayerScoreDictionary<int, int>PlayerIDint

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

你将不得不建立一个[MultiBinding(http://msdn.microsoft.com/en-us/library/ system.windows.data.multibinding.aspx),如[本问题](http://stackoverflow.com/q/13799705/1136211)的答案中所述。 – Clemens

+0

我不知道MVVM。我只是使用源文本和路径=值 – Paparazzi

+0

@Clemens真棒,谢谢你!花了我一段时间来修补我想要的东西,但该解决方案适用于我。 –

回答

3

使用this solution提供通过@Clemens,我能够基于我的字典的数据类型构建自己的DictionaryItemConverter,并创建一个多重绑定方法,将KeyDictionary绑定在一起。

转换器:

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; 
} 
3

绑定到索引的属性是可能的,并使用相同的符号C#,就像你写的:

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

传递给“createFieldBinding”字符串属性路径。如果您设置源作为字典,你只需要通过索引部分,如“[1]”,就好像你在XAML是这样完成的:

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

See this

+0

如果'1'属性是什么? –

+0

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