如何通過用戶的 XAML 將控件動態添加到 UserControl
更新時間:2024-03-11 13:44:15問題闡述
我想創建一個包含 TextBlock 和 St🀅ackPanel 的用戶控件,允許用戶在 XAML 中動態地將他/她自己的控件添加到用戶控件中.
這是我的 UserControl 的示例 XAML:
<UserControl x:Class="A1UserControlLibrary.UserControlStackPanel"
xmlns="//schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="//schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="//schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="//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>
我希望用戶能🙈夠將此用戶控件嵌入到他們的 XAML 中,并將他們自己的控件添加到用戶控件的堆棧面板中:
<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>
使用上述 XAML 執行此操作不起作用.有什么想法嗎?
精準答案
你可以這樣做,雖然不像你的例子完全.你需要兩件事.第一種是聲明一個UIElement
類型的DependencyProperty
,所有控件都擴展它:
public static DependencyProperty InnerContentProperty = DependencyProperty.Register("InnerContent", typeof(UIElement), typeof(YourControl));
public UIElement InnerContent
{
get { return (UIElement)GetValue(InnerContentProperty); }
set { SetValue(InnerContentProperty, value); }
}
第二種是在你希望內容出現的XAML中聲明一個ContentControl
:
<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>
在我看來,如果您使用 StackPanel
s,您可能會發現您的內容無法正確顯示...我建議您使用 Grid
用于除最簡單的布局任務之外的所有布局.
現在與您的示例的一個不同之處在于您將如何使用您的控件.InnerContent
屬性是UIElement
類型,這意味著它可以容納一個 UIElement
.這意味著您需要使用一個容器元素來顯示多個項目,但它具有相同的最終結果:
<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>
結果:
更新>>>
為了記錄,我確切地知道你想做什么.你似乎不明白我在說什么,所以我會嘗試為你解釋最后一次.添加一個 Button
并設置 Tag
屬性,正如我已經向您展示的那樣:
<Button Tag="MyButton1" Content="Click" Click="ButtonClick" />
現在添加一個 Click
處理程序:
private void ButtonClick(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
if (button.Tag = "MyButton1") DoSomething();
}
僅此而已.