我做了最小的项目来证明这个问题:
代码背后:
public partial class AxisControl : UserControl
{
public static readonly DependencyProperty LayoutProperty =
DependencyProperty.Register("Layout", typeof(Orientation), typeof(AxisControl),
new PropertyMetadata(Orientation.Horizontal));
public Orientation Layout
{
get { return (Orientation)GetValue(LayoutProperty); }
set { SetValue(LayoutProperty, value); }
}
public AxisControl()
{
InitializeComponent();
}
}
的Xaml:
<UserControl.Resources>
<ContentControl x:Key="horizontalLayout" Height="60">
<TextBlock Text="{Binding Layout, RelativeSource={RelativeSource AncestorType=UserControl}}" HorizontalAlignment="Center" VerticalAlignment="Bottom"/>
</ContentControl>
<ContentControl x:Key="verticalLayout" Width="60">
<TextBlock Text="{Binding Layout, RelativeSource={RelativeSource AncestorType=UserControl}}" HorizontalAlignment="Left" VerticalAlignment="Center">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</ContentControl>
</UserControl.Resources>
<UserControl.Style>
<Style TargetType="UserControl">
<Style.Setters>
<Setter Property="Content" Value="{StaticResource horizontalLayout}"/>
</Style.Setters>
<Style.Triggers>
<DataTrigger Binding="{Binding Layout, ElementName=root}" Value="Vertical">
<Setter Property="Content" Value="{StaticResource verticalLayout}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
编辑:Xaml现在包含我要在UserControl中安排的元素。
MainWindow Xaml:
<Grid>
<local:AxisControl Layout="Vertical"/>
</Grid>
我们的想法是根据其布局属性设置UserControl的布局,因此我将两个布局放在静态资源中,并根据布局类型为方向设置样式将内容设置为我想要的布局。
编辑:我希望内容根据方向包含以不同顺序排列的元素。
UserControl正确显示,但输出窗口中出现了一个与我有关的错误:
找不到引用'RelativeSource的绑定源 FindAncestor,AncestorType ='System.Windows.Controls.UserControl', AncestorLevel = '1'”。 BindingExpression:路径=布局;的DataItem = NULL; target元素是'TextBlock'(Name ='');目标属性是'文字' (输入'String')
这是否意味着它试图在可能来自触发器的可视树中进行绑定?
请注意在Bindings中使用RelativeSource和ElementName,因为在UserControl的根目录下设置DataContext是不正确的,因为它会破坏DataContext继承。
我做错了什么,如何摆脱错误?
答案 0 :(得分:0)
受到Clemens评论和进一步研究的启发,我意识到我需要为每个布局提供ControlTemplate资源,而不是包含元素本身实例的资源。
<UserControl.Resources>
<ControlTemplate x:Key="horizontalLayout">
<Border Height="60" Background="LightBlue">
<TextBlock Text="{Binding Layout, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center" VerticalAlignment="Bottom"/>
</Border>
</ControlTemplate>
<ControlTemplate x:Key="verticalLayout" TargetType="UserControl">
<Border Width="60" Background="LightBlue">
<TextBlock Text="{Binding Layout, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Left" VerticalAlignment="Center">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Border>
</ControlTemplate>
</UserControl.Resources>
<UserControl.Style>
<Style TargetType="UserControl">
<Style.Setters>
<Setter Property="Template" Value="{StaticResource horizontalLayout}"/>
</Style.Setters>
<Style.Triggers>
<DataTrigger Binding="{Binding Layout, ElementName=root}" Value="Vertical">
<Setter Property="Template" Value="{StaticResource verticalLayout}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
布局=水平
布局=垂直