How to add controls dynamically to a UserControl through user's XAML?
c#, user-controls, wpf, xaml
Solution
You can do that, although not quite like your example. You need two things. The first is to declare a `DependencyProperty` of type `UIElement`, of which all controls extend:
public static DependencyProperty InnerContentProperty = DependencyProperty.Register("InnerContent", typeof(UIElement), typeof(YourControl));
public UIElement InnerContent
{
get { return (UIElement)GetValue(InnerContentProperty); }
set { SetValue(InnerContentProperty, value); }
}
The second is to declare a `ContentControl` in the XAML where you want the content to appear:
<StackPanel>
<TextBlock Text="I want the user to be able to add any number of controls to the StackPanel below this TextBlock."
FontFamily="Arial" FontSize="12" FontWeight="DemiBold" Margin="5,10,5,10" TextWrapping="Wrap"/>
<StackPanel>
<ContentControl Content="{Binding InnerContent, RelativeSource={RelativeSource AncestorType={x:Type YourXmlNamspacePrefix:ContentView}}}" />
</StackPanel>
</StackPanel>
In my opinion, if you use `StackPanel`s, you could find that your content does not get displayed correctly... I'd advise you to use `Grid`s for layout purposes for all but the simplest layout tasks.
Now the one difference to your example is in how you would use your control. The `InnerContent` property is of type `UIElement`, which means that it can hold one `UIElement`. This means that you need to use a container element to display more than one item, but it has the same end result:
<YourXmlNamspacePrefix:YourControl>
<YourXmlNamspacePrefix:YourControl.InnerContent>
<StackPanel x:Name="MyUserControl_Test" Margin="10" Height="100">
<Button Content="Click" Height="30" Width="50"/>
<Button Content="Click" Height="30" Width="50"/>
<Button Content="Click" Height="30" Width="50"/>
</StackPanel>
</YourXmlNamspacePrefix:YourControl.InnerContent>
</YourXmlNamspacePrefix:YourControl>
And the result:
UPDATE >>>
For the record, I know exactly what you want to do. You, it seems, do not understand what I am saying, so I'll try to explain it one last time for you. Add a `Button` with the `Tag` property set as I've already shown you:
<Button Tag="MyButton1" Content="Click" Click="ButtonClick" />
Now add a `Click` handler:
private void ButtonClick(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
if (button.Tag = "MyButton1") DoSomething();
}
That's all there is to it.
Problem
I want to create a user control that contains a TextBlock and a StackPanel that will allow the user to add his/her own controls to the user control dynamically in XAML. Here is the sample XAML for my UserControl: ``` <UserControl x:Class="A1UserControlLibrary.UserControlStackPanel" 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" mc:Ignorable="d" d:DesignHeight="200" d:DesignWidth="300"> <StackPanel> <TextBlock Text="I want the user to be able to add any number of controls to the StackPanel below this TextBlock." FontFamily="Arial" FontSize="12" FontWeight="DemiBold" Margin="5,10,5,10" TextWrapping="Wrap"/> <StackPanel> <!-- I want the user to be able to add any number of controls here --> </StackPanel> </StackPanel> </UserControl> ``` I would like the user to be able to embed this user control in their XAML and add their own controls to the stack panel of the user control: ``` <uc:A1UserControl_StackPanel x:Name="MyUserControl_Test" Margin="10" Height="100"> <Button Name="MyButton1" Content="Click" Height="30" Width="50"/> <Button Name="MyButton2" Content="Click" Height="30" Width="50"/> <Button Name="MyButton3" Content="Click" Height="30" Width="50"/> </uc:A1UserControl_StackPanel> ``` Doing this using the above XAML does not work. Any ideas?