在自定义 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);
}
}
我需要创建自定义 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);
}
}