简体   繁体   中英

WPF: Multiple content presenters in a custom control?

I'm trying to have a custom control that requires 2 or more areas of the XAML to be defined by a child control - that inherits from this control. I'm wondering if there's a way to define multiple contentpresenters and one which acts as the default content presenter

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

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

Is this possible, how do I define this in the custom control's template?

The template can just bind the separate ContentPresenter instances like this (I've only set one property here but you'll likely want to set others):

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

The control itself should expose two properties for content and set the default using the ContentPropertyAttribute :

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

You can use an "ItemsControl" with a custom template.

<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>

Here's another option that doesn't require making a custom control and is more typesafe than doing the ItemsControl thing (if type safety is something you want..perhaps not):

...Use an attached property!

Create an attached property of the appropriate type. We happened to need a text control so I did a string TextContent attached property. Then create a TemplateBinding to it from the template, and when instantiating in Xaml set it there as well. Works nicely.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM