如何在自定义WPF UserControl中正确使用ContentPresenter

时间:2019-01-25 13:02:20

标签: wpf contentpresenter

我想在WPF中有一个自定义UserControl,它基本上只将标题TextBlock放在实际内容上(我在这里将其称为“ AttributePanelItem”。 但是,在我当前的方法中,当我直接分配用户控件的内容时,不会显示TextBlock。

这是我当前针对自定义UserControl的XAML:

<UserControl x:Class="Common.Controls.AttributePanelItem"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             Name="MyAttributePanelItem"
             d:DesignHeight="100" d:DesignWidth="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="{Binding Caption, ElementName=MyAttributePanelItem}"/>
        <ContentPresenter Grid.Row="1" Content="{Binding InputMask, ElementName=MyAttributePanelItem}" />
    </Grid>
</UserControl>

这是后面的代码:

public AttributePanelItem()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty CaptionProperty = DependencyProperty.Register("Caption", typeof(string), typeof(AttributePanelItem), new PropertyMetadata(string.Empty));
        public string Caption
        {
            get { return (string)GetValue(CaptionProperty); }
            set { SetValue(CaptionProperty, value); }
        }

        public static readonly DependencyProperty InputMaskProperty = DependencyProperty.Register("InputMask", typeof(object), typeof(AttributePanelItem), new PropertyMetadata(null));
        public object InputMask
        {
            get { return (object)GetValue(InputMaskProperty); }
            set { SetValue(InputMaskProperty, value); }
        }

这是我当前使用自定义UserControl的XAML:

<controls:AttributePanel>
            <controls:AttributePanelItem Caption="This caption is shown">
                <controls:AttributePanelItem.InputMask>
                    <TextBox Text="This is my input 1" />
                </controls:AttributePanelItem.InputMask>
            </controls:AttributePanelItem>

            <controls:AttributePanelItem Caption="This caption is not shown">
                <TextBox Text="This is my input 2" />
            </controls:AttributePanelItem>

        </controls:AttributePanel>

在我的实现中,我两次使用AttributePanelItem。 1.第一次使用按预期方式工作,但这不是我的最爱。 2.第二种用法是我想要它的方式。不幸的是,在这种情况下,没有显示标题TextBlock。

是否可以使第二种情况起作用(显示标题TextBlock,而不必使用)?

我认为我使用ContentPresenter错误。但是我不知道需要更改什么。

能请你帮忙吗?

1 个答案:

答案 0 :(得分:0)

您对ContentPresenter的使用是正确的,但应在ContentTemplate内。您需要更改UserControl.ContentTemplate才能执行所需的操作:

<UserControl
    x:Class="WpfApp1.AttributePanelItem"
    x:Name="MyAttributePanelItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
    <UserControl.Style>
        <Style TargetType="UserControl">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="UserControl">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <TextBlock Grid.Row="0" Text="{Binding Caption, ElementName=MyAttributePanelItem}" />
                            <ContentPresenter Grid.Row="1" Content="{TemplateBinding Content}" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
         </Style>
    </UserControl.Style>
</UserControl>

现在,您将可以使用第二种用法。实际上,您可以将InputMask中的UserControl完全删除(除非您将其用于其他用途)。