WPF: несколько презентаторов контента в пользовательском элементе управления?

Я пытаюсь создать настраиваемый элемент управления, который требует, чтобы две или более области XAML определялись дочерним элементом управления - который наследуется от этого элемента управления. Мне интересно, есть ли способ определить несколько контентуаторов контента и тот, который действует как презентатор контента по умолчанию

<MyControl>
      <MyControl.MyContentPresenter2>
           <Button Content="I am inside the second content presenter!"/>
      </MyControl.MyContentPresenter2>

      <Button Content="I am inside default content presenter" />
</MyControl>

Возможно ли это, как это определить в шаблоне пользовательского контроля?

Ответ 1

Шаблон может просто связывать отдельные экземпляры ContentPresenter, подобные этому (я установил только одно свойство, но вы, вероятно, захотите установить другие):

<ContentPresenter Content="{TemplateBinding Content1}"/>
<ContentPresenter Content="{TemplateBinding Content2}"/>

Сам элемент управления должен отображать два свойства для содержимого и устанавливать значение по умолчанию с помощью ContentPropertyAttribute:

[ContentProperty("Content1")]
public class MyControl : Control
{
    // dependency properties for Content1 and Content2
    // you might also want Content1Template, Content2Template, Content1TemplateSelector, Content2TemplateSelector
}

Ответ 2

Вы можете использовать "ItemsControl" с настраиваемым шаблоном.

<ItemsControl>
    <ItemsControl.Style>
        <Style TargetType="ItemsControl">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <StackPanel Orientation="Horizontal">
                            <ContentControl Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Items[0]}"/>
                            <ContentControl Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Items[1]}"/>
                            <ContentControl Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Items[2]}"/>
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ItemsControl.Style>
    <TextBlock Text="Item 1"/>
    <TextBlock Text="Item 2"/>
    <TextBlock Text="Item 3"/>
</ItemsControl>

Ответ 3

Вот еще один вариант, который не требует создания настраиваемого элемента управления и более типичен, чем выполнение элемента ItemsControl (если безопасность типов - это то, что вы хотите... возможно, не так):

... Используйте прикрепленное свойство!

Создайте вложенное свойство соответствующего типа. Нам понадобился текстовый элемент управления, поэтому я применил прикрепленное свойство TextContent. Затем создайте для него шаблонную привязку из шаблона, а при создании экземпляра в Xaml также установите его. Хорошо работает.