当前位置: 首页 > 知识库问答 >
问题:

如何通过属性更改UserControl的布局?

濮冠宇
2023-03-14

我做了一个我能证明问题的最小项目:

背后的代码:

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现在包括我想在用户控件中排列的元素。

主窗口 Xaml:

<Grid>
    <local:AxisControl Layout="Vertical"/>
</Grid>

这个想法是根据其布局属性设置 UserControl 的布局,因此我将两种布局都放在静态资源中,并制作了一个样式以根据类型为“方向”的布局将内容设置为我想要的内容。

编辑:我希望内容包含根据方向以不同顺序排列的元素。

用户控件显示正确,但输出窗口中有一个与我有关的错误:

找不到引用“RelativeSource FindAncestor,AncestorType=”System.Windows.Controls的绑定源。UserControl“,AncestorLevel=“1”。BindingExpression:路径=布局;数据项=空;目标元素是“TextBlock”(名称=“”);目标属性为“Text”(类型为“String”)

这是否意味着它正在尝试在可能来自触发器的可视化树中之前执行绑定?

请注意绑定中RelativeSource和ElementName的使用,因为在UserControl的根位置设置DataContext是不正确的,因为它会破坏DataContext继承。

我做错了什么,我怎样才能摆脱错误?

共有1个答案

姬昀
2023-03-14

受到克莱门斯评论和进一步研究的启发,我意识到我需要为每个布局提供一个 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>

布局=水平

布局=垂直

 类似资料:
  • 问题内容: 因此,我最近开始涉足OOP,到目前为止一切进展顺利。虽然我本身没有任何问题,但我希望有一个令人惊奇的功能,尽管我找不到关于该功能的任何文档。 在为对象分配属性时,我经常发现我必须更改依赖于他人的属性,例如光明与黑暗。这是一个例子: 现在,尽管这很酷,但我想要的是相同的过程,但是如果一个属性发生更改,则在同一对象内。如果我重置光的属性(是的),我希望黑暗相应地增加/减少。如果可以更改光的

  • 我试图设置一个系统,当我按下按钮时,JLabel文本会改变,但我似乎无法使其工作。我已经测试了操作监听器通过执行system.out.println(test);来工作。它工作正常,但是当试图更改JComponent文本时,它不工作。我已经搜索了答案,但没有找到任何有用的答案。 主要类别: JFrame和JPanel类: ActionListener类:

  • 我想更改“成员”数据框中“成功”列的布尔值。具体来说,我想把真正的价值观改为“成功”,把错误的价值观改为“失败”。你知道怎么做吗? 代码:

  • 问题内容: 该代码不起作用 问题答案: JavaScript区分大小写。 因此,如果要更改字体大小,则必须执行以下操作:

  • 我需要有关如何更改通过DocuSign向收件人发送电子邮件时显示的名称的帮助。我使用的是REST API,我复制了DocuSign的一个示例。我可以更改电子邮件主题,但我不知道top如何更改电子邮件正文中的[名称]。下面是一个如何更改电子邮件主题的示例。我正在使用c#Web开发。 这些是我想改变的,任何有[名字的东西]: [姓名]通过docusign 提前谢谢你。

  • 我有一个带有子组件的组件。 在时间轴组件中,我有这些属性: 如何检查何时从时间轴组件对属性进行更改?每当编辑值发生更改时,我都需要发出该值。 我应该为编辑属性使用一个setter,然后从那里发出吗? 或者有其他方法吗?