在自定义UserControl上添加额外控件

时间:2015-02-16 14:29:10

标签: c# wpf xaml

我需要创建自定义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个文本框,但它只显示一个,可能是因为内容被父级覆盖。

4 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

如果您想要一个带有两个文本框的自定义用户控件,只需在控件的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>

答案 2 :(得分:0)

在挖掘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的根目录必须有堆栈面板。无论何时我想要提供额外的控制或其他东西都比较容易维护

答案 3 :(得分:0)

但是如果你想从代码中添加它来为网格命名,那么从代码中添加子代。例如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);
    }
}