将WPF绑定到由属性指定的数组的元素 [英] Binding in WPF to element of array specified by property

查看:572
本文介绍了将WPF绑定到由属性指定的数组的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我在我的UI上有一些TextBlocks,如下所示:

 < 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 ,蛋糕,大蒜};
}
}

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

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






编辑:



所以我更密切的是数据是这些对象的列表[]的情况,我使用上面的StackPanel作为ListBox的DataTemplate的一部分。所以,正如马克·希思(Mark Heath)在下面的建议,使用一个取消引用数组的属性看起来不像我想要的那样工作。想法?

解决方案

另一个替代方法是使用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 =MainWindowHeight = 350宽度=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 =食物/>
< / MultiBinding>
< /TextBlock.Text>
< / TextBlock>
< / StackPanel>
< / Window>

然后在代码隐藏中,转换器定义如下:

 命名空间WpfApplication1 
{
public class FoodIndexConverter:IMultiValueConverter
{
public object Convert值,类型targetType,对象参数,System.Globalization.CultureInfo文化)
{
if(values == null || values.Length!= 2)
返回null;

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

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

返回食物[idx.Value];
}

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


Say I've got some TextBlocks on my UI, something like so:

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

and in my code behind I've got something like this:

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

The first two TextBlocks display fine for me, displaying 2 and 'cake' respectively. The third one doesn't accomplish what I'd like, namely use the DessertIndex property to index into that array and also display 'cake'. I did a little searching here on SO for a similar question but didn't find one. Ultimately, I don't want to specify values like 2 in my .xaml file and would like to rely upon a property instead for indexing into that array. Is this possible? If so, what am I doing wrong here?


EDIT:

So what I more closely have is a situation where the data is a List of these object[] and I'm using the above StackPanel as part of a DataTemplate for a ListBox. So the idea, as Mark Heath suggests below, of using a property that dereferences the array doesn't seem to work as I'd want. Ideas?

解决方案

Another alternative is to use MultiBinding with a converter:

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

Then in the code-behind, the converter is defined something like this:

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

这篇关于将WPF绑定到由属性指定的数组的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆