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