Search code examples
c#wpfxamluser-controlscontentpresenter

How to use a ContentPresenter inside a UserControl


I'd like to create a UserControl (in this case a square-Button with defined Backgroundcolors) which can host it's own content.

UserControl:

<UserControl x:Class="SGDB.UI.Controls.ModernButton"
         xmlns:local="clr-namespace:SGDB.UI.Controls"
         xmlns:converter="clr-namespace:SGDB.UI.Converter"
         x:Name="_modernButton">
<Button>
    <Button.Resources>
        <converter:EnumToColorConverter x:Key="ColorConverter"/>
    </Button.Resources>
    <Button.Template>
        <ControlTemplate>
            <Border Width="{Binding Size, ElementName=_modernButton}" Height="{Binding Size, ElementName=_modernButton}" BorderBrush="Black" BorderThickness="0.8,0.8,3,3">
                <Grid Background="{Binding BackgroundColor, ElementName=_modernButton, Converter={StaticResource ColorConverter}}">
                    <ContentPresenter/>
                </Grid>
            </Border>
        </ControlTemplate>
    </Button.Template>
</Button>

Now, as you may expect it, if I use this Control inside my MainView everthing works just fine until I define some Content.

Using:

<control:ModernButton Size="200" BackgroundColor="Light">
    TEST
</control:ModernButton>

In this case "TEST" will override the whole Content of the UserControl (the whole Button Template). I guess this happens because The Button inside the UserControl is defined as "Content" itself and it will get overridden when defining new Content.

So the final question is: Is it possible to achieve what I'm looking for? if yes: How? How could I "redirect" the Content I'm defining in my MainView into the self-defined ContentPresenter inside my Button Template instead of the UserControls's ContentPresenter?

If possible I don't want to create a new dp-propery which hosts my Content, e.g.:

<controls:MordernButton Size="200" BackgroundColor="Light">
    <controls:ModernButton.Content>
        I don't want this, if possible
    </controls:ModernButton.Content>
</controls:ModernButton>

Solution

  • Here we go.

    <UserControl x:Class="SGDB.UI.Controls.ModernButton"
         xmlns:local="clr-namespace:SGDB.UI.Controls"
         xmlns:converter="clr-namespace:SGDB.UI.Converter"
         x:Name="_modernButton">
    
        <UserControl.Template>
            <ControlTemplate TargetType="UserControl">
                <Button Content="{TemplateBinding Content}">
                     <Button.Resources>
                        <converter:EnumToColorConverter x:Key="ColorConverter"/>
                      </Button.Resources>
                <Button.Template >
                    <ControlTemplate TargetType="Button">
                        <Border Width="{Binding Size,
                                        ElementName=_modernButton}"
                        Height="{Binding Size,
                                         ElementName=_modernButton}"
                        BorderBrush="Black"
                        BorderThickness="0.8,0.8,3,3">
                            <Grid Background="{Binding BackgroundColor, ElementName=_modernButton, Converter={StaticResource ColorConverter}}">
                                <ContentPresenter />
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Button.Template>
                </Button>
            </ControlTemplate>
        </UserControl.Template>
    </UserControl>