如何通过用户的 XAML 将控件动态添加到 UserControl?

How to add controls dynamically to a UserControl through user#39;s XAML?(如何通过用户的 XAML 将控件动态添加到 UserControl?)
本文介绍了如何通过用户的 XAML 将控件动态添加到 UserControl?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个包含 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>

在我看来,如果您使用 StackPanels,您可能会发现您的内容无法正确显示...我建议您使用 Grid 用于除最简单的布局任务之外的所有布局.

In my opinion, if you use StackPanels, you could find that your content does not get displayed correctly... I'd advise you to use Grids 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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)