在自定义 UserControl 上添加额外的控制

Add extra control on custom UserControl

我需要创建自定义 UserControl,这样我就可以轻松添加一些控件,这样所有实现 CustomUserControl 的控件都会受到影响。

我就是这样做的

public class CustomUserControl : UserControl
    {
        public CustomUserControl()
        {
            var stack = new StackPanel();
            stack.Children.Add(new TextBox() { Width = 100, Height = 100 });
            Content = stack; // need to add extra control to content
            //AddChild("test"); // this also fail
            //AddChild(stack); // this result in hard error
        }
    }

在xaml

<control:CustomUserControl x:Class="Sample"
             xmlns:control="clr-namespace:Sample.Controls;assembly=Sample"
             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="300" d:DesignWidth="300">
    <Grid>
            <TextBox Width="100" Height="100"/>
    </Grid>
</control:CustomUserControl>

我想让它显示 2 个文本框,但它只显示一个,可能是因为内容被父级覆盖了。

您的构造函数代码在 XAML 生成后执行。您的内容首先在 XAML 中设置为 "Grid",然后在 .cs 文件中设置为 "Content = stack"。您需要在 xaml 中为您的网格设置名称,并在 .cs 文件中使用它的名称。但是请不要这样做,请使用 MVVM。

如果您想要一个带有两个文本框的自定义用户控件,只需在控件的 XAML 中执行:您不需要在构造函数中执行此操作。

换句话说,删除你的构造函数:

public class CustomUserControl : UserControl
{
}

并去掉 XAML 中的 Grid:

<control:CustomUserControl x:Class="Sample" ... >
    <StackPanel>
        <TextBox Width="100" Height="100"/>
        <TextBox Width="100" Height="100"/>
    </StackPanel>
</control:CustomUserControl>

在挖掘 UserControl 和试错之后,我终于得到了我想要的,只需在用户控件中重写渲染即可

protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
        {
            if (_group == null) //private field, hack so it only adding content once
            {
                var grid = new StackPanel() { Orientation = Orientation.Vertical };
                _group = new WarningBoxControl();

                var content = Content as StackPanel;
                if (content != null)
                {
                    _group.DataContext = content.DataContext;
                    content.Children.Insert(0, _group);
                }
            }

            base.OnRender(drawingContext);
        }

唯一的问题是实现 CustomUserControl 的控件必须在其根部有堆栈面板。无论何时我想进行额外控制或其他操作时,这都更容易维护

但是如果你想从代码中添加它,你给网格命名,然后从代码中添加孩子。例如 XAML:

<UserControl x:Class="WpfApplication1.UserControl1"
         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="300" d:DesignWidth="300">
<Grid x:Name="MyGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="29*"/>
        <RowDefinition Height="271*"/>
    </Grid.RowDefinitions>
    <TextBlock Text="TextBox1 Text" Grid.Row="0"/>
</Grid>

.cs 文件将是:

public UserControl1()
    {
        InitializeComponent();
        var textBlock2 = new TextBlock();
        textBlock2.Text = "TextBox2 Text";
        MyGrid.Children.Add(textBlock2);
        Grid.SetRow(textBlock2,1);
    }
}