代码之家  ›  专栏  ›  技术社区  ›  itsmatt

在wpf中绑定到属性指定的数组元素

  •  28
  • itsmatt  · 技术社区  · 14 年前

    假设我的用户界面上有一些文本块,比如:

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

    前两个文本块对我显示很好,分别显示2和“cake”。第三个没有完成我想要的,即使用DessertIndex属性对数组进行索引并显示“cake”。我在这里搜索了一下,所以找不到类似的问题。最后,我不想在.xaml文件中指定类似2的值,而是希望依赖属性来索引到该数组中。这有可能吗?如果是的话,我在这里做错了什么?


    编辑:

    所以我更接近的情况是,数据是这些对象的列表,我使用上面的stackpanel作为列表框的数据模板的一部分。所以,正如下面马克·希思所建议的,使用一个取消引用数组的属性的想法,似乎并不像我希望的那样有效。主意?

    2 回复  |  直到 14 年前
        1
  •  29
  •   Colin Thomsen    14 年前

    另一种选择是使用转换器的多重绑定:

    <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();
            }
        }
    }
    
        2
  •  12
  •   Mark Heath    14 年前

    如果你要有一个 DesertIndex 属性在您的DataContext上,为什么不使用沙漠索引取消对食物数组的引用:

    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对象具有刚好适合绑定到的属性。