Как правильно использовать ContentPresenter в пользовательском WPF UserControl - PullRequest
0 голосов
/ 25 января 2019

Я хочу иметь пользовательский элемент управления UserControl в WPF, который в основном только помещает заголовок TextBlock поверх фактического содержимого (здесь я называю его «AttributePanelItem». Однако в моем текущем подходе TextBlock не отображается, когда я задаю Content)пользовательский элемент управления.

Это мой текущий XAML для пользовательского UserControl:

<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); }
        }

Это мой текущий XAML для использованияПользовательский UserControl:

<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 голосов
/ 25 января 2019

Вы используете 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 (если вы не используете его для чего-то другого).

...