2010-11-04 37 views
25

说指定数组的元素我有我的UI部分的TextBlocks,像这样的东西:在WPF绑定到地产

<StackPanel Orientation="Vertical"> 
    <TextBlock Text="{Binding DessertIndex}" /> 
    <TextBlock Text="{Binding Food[2]}" /> 
    <TextBlock Text="{Binding Food[{Binding DessertIndex}]}" /> 
</StackPanel> 

,并在我的代码后面我有这样的事情:

public partial class MainWindow : Window 
{ 
    public int DessertIndex 
    { 
     get { return 2; } 
    } 

    public object[] Food 
    { 
     get 
     { 
      return new object[]{"liver", "spam", "cake", "garlic" }; 
     } 
    } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = this; 
    } 
} 

前两个TextBlocks对我来说很好,分别显示2和'cake'。第三个不完成我想要的,即使用DessertIndex属性来索引该数组,并显示'蛋糕'。我在这里搜索了一个类似的问题,但没有找到。最终,我不想在我的.xaml文件中指定像2那样的值,并且想要依靠属性来索引该数组。这可能吗?如果是这样,我在这里做错了什么?


编辑:

所以我更加仔细地是数据为这些对象[]列表的情况,我在上面使用的StackPanel中作为一个ListBox一个DataTemplate的一部分。所以这个想法,正如Mark Heath在下面提出的那样,使用一个解引用数组的属性似乎并不像我想要的那样工作。想法?

回答

26

另一种方法是使用MultiBinding用转换器:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfApplication1" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel Orientation="Vertical"> 
     <StackPanel.Resources> 
      <local:FoodIndexConverter x:Key="foodIndexConverter" /> 
     </StackPanel.Resources> 
     <TextBlock Text="{Binding DessertIndex}" /> 
     <TextBlock Text="{Binding Food[2]}" /> 
     <TextBlock> 
       <TextBlock.Text> 
        <MultiBinding Converter="{StaticResource foodIndexConverter}"> 
         <Binding Path="DessertIndex" /> 
         <Binding Path="Food"/> 
        </MultiBinding> 
       </TextBlock.Text> 
     </TextBlock> 
    </StackPanel> 
</Window> 

然后在后台代码,转换器定义是这样的:

namespace WpfApplication1 
{ 
    public class FoodIndexConverter : IMultiValueConverter 
    { 
     public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (values == null || values.Length != 2) 
       return null; 

      int? idx = values[0] as int?; 
      object[] food = values[1] as object[]; 

      if (!idx.HasValue || food == null) 
       return null; 

      return food[idx.Value]; 
     } 

     public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 
+0

感谢科林 - 这对我的测试应用程序非常有效,并且怀疑它在真实情况下也能正常工作。今天过得很愉快 - 我从你身上学到了很酷的东西。 :) – itsmatt 2010-11-04 20:42:51

+2

您可能会尝试使用ConverterParameter尝试不同的方法来避免多重绑定。不幸的是,这将无处可去,因为ConverterParameter无法使用绑定,因为它不是DependencyProperty,并且您必须使用MultiBinding – 2013-10-09 09:56:29

10

,如果你要对你的DataContext,有DesertIndex财产的麻烦,为什么不取消引用粮食阵列DesertIndex属性:

public object SelectedFood 
{ 
    get { return Food[DessertIndex]; } 
}  

public int DessertIndex 
{ 
    get { return 2; } 
} 

public object[] Food 
{ 
    get 
    { 
     return new object[]{"liver", "spam", "cake", "garlic" }; 
    } 
} 

那么你可以直接绑定到:

<TextBlock Text="{Binding SelectedFood}" /> 

这实质上就是“MVVM”方法:使datacontext对象具有适合绑定的属性。

+0

马克,感谢您的答复。有关更多详细信息,请参阅我对原始问题的编辑。基本上,我正在处理一个ListBox和这些对象的列表[]的,所以我不知道如何在这个上下文中建议工作。数据不是我的,我必须照原样处理。想法? – itsmatt 2010-11-04 20:16:07

+0

是的,我确实怀疑这是否可能。 – 2010-11-04 20:28:09