Home > Mobile >  RelativeSource binding in ItemsControl doesn't work
RelativeSource binding in ItemsControl doesn't work

Time:11-15

I'm stuck on the following binding problem. I have the following class declarations in MainWindow.xaml.cs:

    public List<MyArrayClass> MyArrayData { get; set; }
    public class MyArrayClass
    {
        public ObservableCollection<int> MyArrayInt { get; set; }
        public ObservableCollection<Thickness> MyArrayBorder { get; set; }
    }

And I create the object as follows:

        MyArrayClass sample3 = new MyArrayClass
        {
            MyArrayInt = new ObservableCollection<int> { 0, 1, 2, 3 },
            MyArrayBorder = new ObservableCollection<Thickness> { new Thickness(0,0,0,2), new Thickness(0, 0, 0, 2), new Thickness(0, 0, 0, 2), new Thickness(0, 0, 0, 2) }
        };

        MyArrayData = new List<MyArrayClass>();
        MyArrayData.Add(sample3);

Having said that, my objective is to display the contents of MyArrayInt into a set of TextBlocks using the ItemsControl object (I'm trying to understand how it works). In particular, I want to be able to define the border of each TextBlock via binding. My XAML looks like:

<ItemsControl Name="List" ItemsSource="{Binding MyArrayData}" Grid.Row="1" Grid.Column="1">
        <!-- List<> -->
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ItemsControl Name="MyArrayInt" ItemsSource="{Binding MyArrayInt}">
                    <!-- Array of int-->
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Border BorderBrush="Red" BorderThickness="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}, AncestorLevel=2}, Path=MyArrayBorder}">
                                <TextBlock Text="{Binding Path=.}" Background="Azure" Margin="2,0,0,0"/>
                            </Border>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

The result is that MyArrayInt is displayed as I expect, but I get the following error on the BorderThickness binding:

System.Windows.Data Error: 40 : BindingExpression path error: 'MyArrayBorder' property not found on 'object' ''ItemsControl' (Name='List')'. BindingExpression:Path=MyArrayBorder; DataItem='ItemsControl' (Name='List'); target element is 'Border' (Name=''); target property is 'BorderThickness' (type 'Thickness')

The way I read it, it seems that the RelativeSource binding is correct: the Name of the ItemsControl object is 'List', and it's the one binding to MyArrayData. So why doesn't it find MyArrayBorder?

Any suggestion or advice is welcome!

CodePudding user response:

your binding is wrong. you can use ListBox or ListItem instead of ItemsControl and then set BorderThickness="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}, AncestorLevel=2}, Path=SelectedItem.MyArrayBorder}"

CodePudding user response:

Because ItemsControl (Name='List')' does not have MyArrayBorder property, but it's DataContext has.

So to access the property you have to set Path=DataContext.MyArrayData.MyArrayBorder.

But as I can see you want to set the BorderThikness but you have to set it to the one entry from list, not to the list.
So something like Path=DataContext.MyArrayData.MyArrayBorder[0].

  • Related