简体   繁体   中英

Binding inside an ItemsSource defined in XAML

I want to define the ItemsSource of an ItemsControl in XAML and in those items use data binding to the DataContext of my view, but I cannot get it to work.

Here is what a simplified version would look like:

<ComboBox DisplayMemberPath="Label" DataContext="Item 3">
    <ComboBox.ItemsSource>
        <x:Array Type="{x:Type local:Item}">
            <local:Item Label="Item 1" />
            <local:Item Label="{Binding}" />
        </x:Array>
    </ComboBox.ItemsSource>
</ComboBox>

with the Item defined like this:

public class Item : DependencyObject
{
    public static readonly DependencyProperty LabelProperty =
        DependencyProperty.Register(nameof(Label), typeof(string), typeof(Item));

    public string Label
    {
        get { return (string)GetValue(LabelProperty); }
        set { SetValue(LabelProperty, value); }
    }
}

I am expecting to see two items in the ComboBox with "Item 1" and "Item 2" as text, but the second item has a blank text. Why?

You want to override the ItemTemplate for the ComboBox , an example is shown below:

<ComboBox x:Name="ExampleComboBox"
          Height="24"
          Width="200"
          HorizontalContentAlignment="Stretch">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="10" />
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="10" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>

                    <TextBlock Grid.Column="0"
                               Text="{Binding FirstName}" />
                    <TextBlock Grid.Column="2"
                               Text="{Binding LastName}" />
                    <TextBlock Grid.Column="4"
                               HorizontalAlignment="Right"
                               Text="{Binding Country}" />
                </Grid>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

The example output is shown below:

在此处输入图片说明

I finally found an explanation! The ItemsSource is not in the visual tree, that's why the binding is not working. I have found a great explanation and a workaround here: https://stackoverflow.com/a/7661689 , that led me to another (similar) workaround here: http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/ .

Using the latter, my code now looks like this (in this somewhat overly simplified and rather stupide example):

<ComboBox DisplayMemberPath="Label" DataContext="Item 3">
    <ComboBox.Resources>
        <local:BindingProxy x:Key="proxy" Data="{Binding}" />
    </ComboBox.Resources>
    <ComboBox.ItemsSource>
        <x:Array Type="{x:Type local:Item}">
            <local:Item Label="Item 1" />
            <local:Item Label="{Binding Data, Source={StaticResource proxy}}" />
        </x:Array>
    </ComboBox.ItemsSource>
</ComboBox>

And it works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM