How to use a ContentPresenter inside a UserControl
Use the ContentPropertyAttribute
to instruct the xaml to set this property instead of the actual Content property.
[ContentProperty("InnerContent")]public partial class ModernButton : UserControl{ public ModernButton() { InitializeComponent(); } public static readonly DependencyProperty InnerContentProperty = DependencyProperty.Register("InnerContent", typeof(object), typeof(ModernButton)); public object InnerContent { get { return (object)GetValue(InnerContentProperty); } set { SetValue(InnerContentProperty, value); } }}
Then in your xaml, Bind the Content Presenter to use InnerContent property instead.
<ContentPresenter Content="{Binding InnerContent, ElementName=_modernButton}"/>
This way you can do the following without replacing the actual content.
<control:ModernButton Size="200" BackgroundColor="Light"> TEST</control:ModernButton>
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>
Let's assume that youre UserControl is:
<UserControl x:Class="QuickAndDirtyAttempt.Decorator" .... <UserControl.Template> <ControlTemplate TargetType="{x:Type local:Decorator}"> <StackPanel Orientation="Vertical"> <Label>Foo</Label> <ContentPresenter/> <Label>Bar</Label> </StackPanel> </ControlTemplate> </UserControl.Template></UserControl>
Note the TargetType property on the template: without it the project will happily compile, but the ContentPresenter will not work.And then:
<Window ... > <StackPanel Orientation="Vertical"> <local:Decorator> <Label Background="Wheat">User supplied content here</Label> </local:Decorator> </StackPanel></Window>
I strongly recommend you to read this before implementing anything