I'm looking to set a UserControl
to be the Content
of another UserControl
in XAML, in the same way you can set a Button's
Content
to be anything.
Let's say my "outer" UserControl
looks like this:
<MyUserControl>
<Grid>
<Border FancyPantsStyling="True">
<-- I want to insert other controls here -->
</Border>
</Grid>
</MyUserControl>
And I'd like to instantiate this way:
<local:MyUserControl>
<local:MyUserControl.Content>
<local:AnotherControl />
</local:MyUserControl.Content>
</local:MyUserControl>
How do I design MyUserControl
to render it's Content
in a specific location?
All the stuff you put into your UserControl's XAML is its Content so you can't inject something else by setting the Content property. There are a few different ways you could handle this. If you don't have anything in the code-behind for MyUserControl you can just get rid of it and use something like:
<ContentControl>
<ContentControl.Template>
<ControlTemplate TargetType="{x:Type ContentControl}">
<Grid>
<Border FancyPantsStyling="True">
<ContentPresenter/>
</Border>
</Grid>
</ControlTemplate>
</ContentControl.Template>
<local:AnotherControl/>
</ContentControl>
If you have code behind that doesn't access the XAML elements directly you can do a similar thing with your existing control (since UC derives from ContentControl):
<local:MyUserControl>
<local:MyUserControl.Template>
<ControlTemplate TargetType="{x:Type local:MyUserControl}">
<Grid>
<Border FancyPantsStyling="True">
<ContentPresenter/>
</Border>
</Grid>
</ControlTemplate>
</local:MyUserControl.Template>
</local:MyUserControl>
If you need to keep the existing content connected to your code-behind you can use a DataTemplate to pass in the external content (into a new DP on MyUserControl) and apply that template to a ContentControl in the UC's XAML.
I got an idea, then tried it and it worked for me. I just wanted to share this to other people. I hope it will be useful.
The video link which explains what is the end of the solution: Video Link
The basic idea is to create UIElement DependencyProperty instead of creating Border DependencyProperty
Firstly, you should add your borders or panels or whatever you want to your user control (in your case it'S "MyUserControl") and make sure it has a name to access from .cs file:
<Border x:Name="LeftBorder" Grid.Column="0">
Then you should add a public UIElement value to your user control (in your case it's "MyUserControl"):
public UIElement LeftBorderChild
{
get { return (UIElement)GetValue(LeftBorderChildProperty ); }
set { SetValue(LeftBorderChildProperty , value); }
}
Secondly, type of your Dependencyproperty must be UIElement:
public static readonly DependencyProperty LeftBorderChildProperty = DependencyProperty.Register("LeftBorderChild", typeof(UIElement), typeof(MyUserControl), new PropertyMetadata(new PropertyChangedCallback(LeftBorderChildChanged)));
After these, typing events:
public static void LeftBorderChildChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MyUserControl thisUserControl = d as MyUserControl;
thisCombobox._LeftBorderChildChanged(e); // Calling local event. The new child will be added in this local event function.
}
public void _LeftBorderChildChanged(DependencyPropertyChangedEventArgs e)
{
// In this function, new child element will be added to inside of LeftBorder
this.LeftBorder.Child = (UIElement)e.NewValue; // Sets left border child
}
We're done with this class. Let's call it from other class and add a control inside of it.
<local:MyUserControl Width="312" HorizontalAlignment="Right"
Margin="48, 0, 0, 0" VerticalAlignment="Center"
Height="56" >
<local:MyUserControl.LeftBorder>
<-- You can insert another control here -->
<-- Just don't remember that if you want to add more than one controls, you should add a panel then add controls into inside of the panel because Border child can only 1 child item -->
<StackPanel>
<-- Now you can insert your controls -->
</StackPanel>
</local:MyUserControl.LeftBorder>
</local:MyUserControl>
Note: When you do this firstly, you have to run your program before viewing in xaml designer. After running your program, all design systems are going to run synchronously. I hope i understood what you mean and answered correctly. Thank You
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With