问题描述
我想创建一个包含 TextBlock 和 StackPanel 的用户控件,允许用户在 XAML 中动态地将他/她自己的控件添加到用户控件中.
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.
这是我的 UserControl 的示例 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>
我希望用户能够将此用户控件嵌入到他们的 XAML 中,并将他们自己的控件添加到用户控件的堆栈面板中:
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>
使用上述 XAML 执行此操作不起作用.有什么想法吗?
Doing this using the above XAML does not work. Any ideas?
推荐答案
你可以这样做,虽然不像你的例子完全.你需要两件事.第一种是声明一个UIElement
类型的DependencyProperty
,所有控件都扩展它:
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); }
}
第二种是在你希望内容出现的XAML中声明一个ContentControl
:
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>
在我看来,如果您使用 StackPanel
s,您可能会发现您的内容无法正确显示...我建议您使用 Grid
用于除最简单的布局任务之外的所有布局.
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.
现在与您的示例的一个不同之处在于您将如何使用您的控件.InnerContent
属性是UIElement
类型,这意味着它可以容纳一个 UIElement
.这意味着您需要使用一个容器元素来显示多个项目,但它具有相同的最终结果:
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>
结果:
更新>>>
为了记录,我确切地知道你想做什么.你似乎不明白我在说什么,所以我会尝试为你解释最后一次.添加一个 Button
并设置 Tag
属性,正如我已经向您展示的那样:
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" />
现在添加一个 Click
处理程序:
Now add a Click
handler:
private void ButtonClick(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
if (button.Tag = "MyButton1") DoSomething();
}
仅此而已.
这篇关于如何通过用户的 XAML 将控件动态添加到 UserControl?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!