How to create a WPF UserControl with NAMED content How to create a WPF UserControl with NAMED content wpf wpf

How to create a WPF UserControl with NAMED content


The answer is to not use a UserControl to do it.

Create a class that extends ContentControl

public class MyFunkyControl : ContentControl{    public static readonly DependencyProperty HeadingProperty =        DependencyProperty.Register("Heading", typeof(string),        typeof(MyFunkyControl), new PropertyMetadata(HeadingChanged));    private static void HeadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)    {        ((MyFunkyControl) d).Heading = e.NewValue as string;    }    public string Heading { get; set; }}

then use a style to specify the contents

<Style TargetType="control:MyFunkyControl">    <Setter Property="Template">        <Setter.Value>            <ControlTemplate TargetType="control:MyFunkyControl">                <Grid>                    <ContentControl Content="{TemplateBinding Content}"/>                </Grid>            </ControlTemplate>        </Setter.Value>    </Setter></Style>

and finally - use it

<control:MyFunkyControl Heading="Some heading!">                <Label Name="WithAName">Some cool content</Label></control:MyFunkyControl>


It seems this is not possible when XAML is used. Custom controls seem to be a overkill when I actually have all the controls I need, but just need to group them together with a small bit of logic and allow named content.

The solution on JD's blog as mackenir suggests, seems to have the best compromise. A way to extend JD's solution to allow controls to still be defined in XAML could be as follows:

    protected override void OnInitialized(EventArgs e)    {        base.OnInitialized(e);        var grid = new Grid();        var content = new ContentPresenter                          {                              Content = Content                          };        var userControl = new UserControlDefinedInXAML();        userControl.aStackPanel.Children.Add(content);        grid.Children.Add(userControl);        Content = grid;               }

In my example above I have created a user control called UserControlDefinedInXAML which is define like any normal user controls using XAML. In my UserControlDefinedInXAML I have a StackPanel called aStackPanel within which I want my named content to appear.


Another alternative I've used is to just set the Name property in the Loaded event.

In my case, I had a rather complex control which I didn't want to create in the code-behind, and it looked for an optional control with a specific name for certain behavior, and since I noticed I could set the name in a DataTemplate I figured I could do it in the Loaded event too.

private void Button_Loaded(object sender, RoutedEventArgs e){    Button b = sender as Button;    b.Name = "buttonName";}