ItemsControl 中的 RelativeSource 绑定不起作用
RelativeSource binding in ItemsControl doesn't work
我遇到了以下绑定问题。我在 MainWindow.xaml.cs 中有以下 class 声明:
public List<MyArrayClass> MyArrayData { get; set; }
public class MyArrayClass
{
public ObservableCollection<int> MyArrayInt { get; set; }
public ObservableCollection<Thickness> MyArrayBorder { get; set; }
}
我创建对象如下:
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);
话虽如此,我的 objective 是使用 ItemsControl 对象将 MyArrayInt 的内容显示到一组 TextBlock 中(我试图了解它是如何工作的)。特别是,我希望能够通过绑定定义每个 TextBlock 的边框。我的 XAML 看起来像:
<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>
结果如我所料显示了 MyArrayInt,但我在 BorderThickness 绑定上收到以下错误:
System.Windows.Data 错误:40:BindingExpression 路径错误:'MyArrayBorder' 属性 未在 'object' ''ItemsControl' 上找到(名称='List' )'。 BindingExpression:Path=MyArrayBorder; DataItem='ItemsControl' (名称='List');目标元素是 'Border' (Name='');目标 属性 是 'BorderThickness'(类型 'Thickness')
按照我的阅读方式,RelativeSource 绑定似乎是正确的:ItemsControl 对象的名称是 'List',它是绑定到 MyArrayData 的对象。那么为什么它找不到 MyArrayBorder?
欢迎提出任何建议!
你的绑定有误。
您可以使用 ListBox 或 ListItem 而不是 ItemsControl
然后设置
BorderThickness="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}, AncestorLevel=2}, Path=SelectedItem.MyArrayBorder}"
与其在 MyArrayClass
中拥有两个集合属性,不如创建一个自定义类型并将它们合并为一个:
public class MyArrayClass
{
public ObservableCollection<MyType> MyArray { get; set; }
}
...
public class MyType
{
public int MyArrayInt { get; set; }
public Thickness MyArrayBorder { get; set; }
}
然后您可以轻松绑定到新类型中的每个属性:
<ItemsControl Name="MyArrayInt" ItemsSource="{Binding MyArray}">
<!-- Array of int-->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Red" BorderThickness="{Binding MyArrayBorder}">
<TextBlock Text="{Binding MyArrayInt}" Background="Azure" Margin="2,0,0,0"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
鉴于您当前的设置,您需要使用转换器才能从 MyArrayClass
的 MyArrayBorder
集合中获取特定项目。
您确实可以轻松绑定到 MyArrayBorder
属性 本身:
BorderThickness="{Binding Path=MyArrayBorder[0],
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}"
...但是您不能使用纯 XAML.
绑定到动态索引处的项目(在上面的截图中用 0
替换)
我遇到了以下绑定问题。我在 MainWindow.xaml.cs 中有以下 class 声明:
public List<MyArrayClass> MyArrayData { get; set; }
public class MyArrayClass
{
public ObservableCollection<int> MyArrayInt { get; set; }
public ObservableCollection<Thickness> MyArrayBorder { get; set; }
}
我创建对象如下:
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);
话虽如此,我的 objective 是使用 ItemsControl 对象将 MyArrayInt 的内容显示到一组 TextBlock 中(我试图了解它是如何工作的)。特别是,我希望能够通过绑定定义每个 TextBlock 的边框。我的 XAML 看起来像:
<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>
结果如我所料显示了 MyArrayInt,但我在 BorderThickness 绑定上收到以下错误:
System.Windows.Data 错误:40:BindingExpression 路径错误:'MyArrayBorder' 属性 未在 'object' ''ItemsControl' 上找到(名称='List' )'。 BindingExpression:Path=MyArrayBorder; DataItem='ItemsControl' (名称='List');目标元素是 'Border' (Name='');目标 属性 是 'BorderThickness'(类型 'Thickness')
按照我的阅读方式,RelativeSource 绑定似乎是正确的:ItemsControl 对象的名称是 'List',它是绑定到 MyArrayData 的对象。那么为什么它找不到 MyArrayBorder?
欢迎提出任何建议!
你的绑定有误。 您可以使用 ListBox 或 ListItem 而不是 ItemsControl 然后设置 BorderThickness="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}, AncestorLevel=2}, Path=SelectedItem.MyArrayBorder}"
与其在 MyArrayClass
中拥有两个集合属性,不如创建一个自定义类型并将它们合并为一个:
public class MyArrayClass
{
public ObservableCollection<MyType> MyArray { get; set; }
}
...
public class MyType
{
public int MyArrayInt { get; set; }
public Thickness MyArrayBorder { get; set; }
}
然后您可以轻松绑定到新类型中的每个属性:
<ItemsControl Name="MyArrayInt" ItemsSource="{Binding MyArray}">
<!-- Array of int-->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Red" BorderThickness="{Binding MyArrayBorder}">
<TextBlock Text="{Binding MyArrayInt}" Background="Azure" Margin="2,0,0,0"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
鉴于您当前的设置,您需要使用转换器才能从 MyArrayClass
的 MyArrayBorder
集合中获取特定项目。
您确实可以轻松绑定到 MyArrayBorder
属性 本身:
BorderThickness="{Binding Path=MyArrayBorder[0],
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}"
...但是您不能使用纯 XAML.
绑定到动态索引处的项目(在上面的截图中用0
替换)