Привязка в WPF к элементу массива, указанному свойством - PullRequest
28 голосов
/ 04 ноября 2010

Скажем, у меня есть несколько текстовых блоков в моем пользовательском интерфейсе, что-то вроде этого:

<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 и «торт» соответственно.Третий не выполняет то, что я хотел бы, а именно использовать свойство DessertIndex для индексации в этом массиве, а также для отображения «торт».Я немного искал здесь на SO похожий вопрос, но не нашел.В конечном счете, я не хочу указывать значения, такие как 2, в моем файле .xaml и хотел бы использовать свойство вместо индексации в этом массиве.Это возможно?Если так, что я здесь делаю не так?


РЕДАКТИРОВАТЬ:

Итак, что мне более близко, так это ситуация, когда данные представляют собой список этих объектов [], и я 'используя вышеупомянутую StackPanel как часть DataTemplate для ListBox.Таким образом, идея, как предлагает Марк Хит ниже, использовать свойство, которое разыменовывает массив, похоже, не работает так, как мне хотелось бы.Идеи?

Ответы [ 2 ]

29 голосов
/ 04 ноября 2010

Другой альтернативой является использование 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>

Затем в коде позади конвертера определяется что-то вроде этого:

12 голосов
/ 04 ноября 2010

если у вас возникнет проблема с наличием свойства DesertIndex в вашем DataContext, почему бы не свойство, которое разыменовывает массив Food с 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 имел свойства, подходящие для привязки к нему.

...