How to create WPF usercontrol which contains placeholders for later usage How to create WPF usercontrol which contains placeholders for later usage wpf wpf

How to create WPF usercontrol which contains placeholders for later usage


ContentControls & ItemsControls are good for this, you can bind them to a property of your UserControl or expose them.

Using a ContentControl (for placeholders in multiple disconnected places):

<UserControl x:Class="Test.UserControls.MyUserControl2"             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"              Name="control">    <Grid>        <Button>Just a button</Button>        <ContentControl Content="{Binding PlaceHolder1, ElementName=control}"/>    </Grid></UserControl>
public partial class MyUserControl2 : UserControl{    public static readonly DependencyProperty PlaceHolder1Property =        DependencyProperty.Register("PlaceHolder1", typeof(object), typeof(MyUserControl2), new UIPropertyMetadata(null));    public object PlaceHolder1    {        get { return (object)GetValue(PlaceHolder1Property); }        set { SetValue(PlaceHolder1Property, value); }    }    public MyUserControl2()    {        InitializeComponent();    }}
<uc:MyUserControl2>    <uc:MyUserControl2.PlaceHolder1>        <TextBlock Text="Test"/>    </uc:MyUserControl2.PlaceHolder1></uc:MyUserControl2>

ItemsControl-Version (for collections in one place)

<UserControl x:Class="Test.UserControls.MyUserControl2"             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"             Name="control">    <Grid>        <Button>Just a button</Button>        <ItemsControl Name="_itemsControl" ItemsSource="{Binding ItemsSource, ElementName=control}"/>    </Grid></UserControl>
[ContentProperty("Items")]public partial class MyUserControl2 : UserControl{    public static readonly DependencyProperty ItemsSourceProperty =         ItemsControl.ItemsSourceProperty.AddOwner(typeof(MyUserControl2));    public IEnumerable ItemsSource    {        get { return (IEnumerable)GetValue(ItemsSourceProperty); }        set { SetValue(ItemsSourceProperty, value); }    }    public ItemCollection Items    {        get { return _itemsControl.Items; }    }    public MyUserControl2()    {        InitializeComponent();    }}
<uc:MyUserControl2>    <TextBlock Text="Test"/>    <TextBlock Text="Test"/></uc:MyUserControl2>

With UserControls you can decide to expose certain properties of internal controls; besides the ItemsSource one probably would want to also expose properties like the ItemsControl.ItemTemplate, but it all depends on how you want to use it, if you just set the Items then you do not necessarily need any of that.


I think you want to set your UserControl's ControlTemplate with a ContentPresenter located inside (so you can define where the Content will be presented).

Your Custom UserControl:

<UserControl x:Class="TestApp11.UserControl1"             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">    <UserControl.Template>        <ControlTemplate>            <StackPanel>                <TextBlock Text="Custom Control Text Area 1" />                <ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />                <TextBlock Text="Custom Control Text Area 2" />            </StackPanel>        </ControlTemplate>    </UserControl.Template></UserControl>

Usage:

<Window x:Class="TestApp11.MainWindow"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:l="clr-namespace:TestApp11"    Title="Window1" Height="250" Width="200">    <StackPanel>        <l:UserControl1>            <Button Content="My Control's Content" />        </l:UserControl1>    </StackPanel></Window>

enter image description here

If you need multiple items in your content section, simply place them in a container like a grid or a stackpanel:

<l:UserControl1>    <StackPanel>        <Button Content="Button 1" />        <Button Content="Button 2" />    </StackPanel></l:UserControl1>