我对 wpf 很陌生。
我正在尝试制作一个带有一些精美设计边框的自定义面板。我让一切正常,但前提是我在自定义面板中只有 1 个控件。如果我尝试添加多个,则会出现以下异常:
对象“BordersPanel”已经有一个孩子,不能添加“按钮”。'BordersPanel' 只能接受一个孩子。
我花了很多时间试图在网上找到解决方案,但到目前为止还没有。所以我正在向社区寻求帮助。
面板样式:
<Style
TargetType="{x:Type local:BordersPanel}">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type local:BordersPanel}">
<Grid Margin="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="10.8" />
<RowDefinition Height="*" />
<RowDefinition Height="10.8" />
</Grid.RowDefinitions>
<local:Border
x:Name="topBorder"
Grid.Row="0"
Margin="0"
HorizontalAlignment="Stretch"
VerticalAlignment="top"
BlocksSize="{TemplateBinding BlocksSize}"
Width="Auto"
Height="10.8"/>
<ScrollViewer
Grid.Row="1"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<ContentPresenter
Cursor="{TemplateBinding Cursor}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"/>
</ScrollViewer>
<local:Border
x:Name="bottomBorder"
Grid.Row="2"
Margin="0"
VerticalAlignment="Bottom"
HorizontalAlignment="Stretch"
BlocksSize="{TemplateBinding BottomBlocksSize}"
Width="Auto"
Height="10.8"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
后面的 C# 代码:
class BordersPanel : ContentControl
{
public static readonly DependencyProperty BlocksSizeProperty =
DependencyProperty.Register("BlocksSize", typeof(string), typeof(BordersPanel));
public static readonly DependencyProperty BottomBlocksSizeProperty =
DependencyProperty.Register("BottomBlocksSize", typeof(string), typeof(BordersPanel));
private Border topBorder;
private Border bottomBorder;
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == BordersPanel.BlocksSizeProperty)
{
BottomBlocksSize = BlocksSize + ";T";
}
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
topBorder = GetTemplateChild("topBorder") as Border;
bottomBorder = GetTemplateChild("bottomBorder") as Border;
}
static BordersPanel()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(BordersPanel),
new FrameworkPropertyMetadata(typeof(BordersPanel)));
}
public BordersPanel()
{
SizeChanged += new SizeChangedEventHandler(Border_SizeChanged);
}
public string BlocksSize
{
get
{
return (string)GetValue(BlocksSizeProperty);
}
set
{
SetValue(BlocksSizeProperty, value);
}
}
protected string BottomBlocksSize
{
get
{
return (string)GetValue(BottomBlocksSizeProperty);
}
set
{
SetValue(BottomBlocksSizeProperty, value);
}
}
private void Border_SizeChanged(object sender, SizeChangedEventArgs e)
{
double available = Width;
if (Double.IsNaN(available) == true)
{
available = ActualWidth;
}
if (topBorder != null)
{
topBorder.Width = available;
}
if (bottomBorder != null)
{
bottomBorder.Width = available;
}
}
}
这就是我使用它的方式:
<local:BordersPanel
BlocksSize="LL50;ML50;RU"
Height="208" Canvas.Left="213" Canvas.Top="56.82" Width="428.5">
<local:BinarySquares Margin="0,0,10,15" HorizontalAlignment="Right" VerticalAlignment="Bottom" d:LayoutOverrides="Width, Height"/>
<Button Content="Button" HorizontalAlignment="Stretch" Height="300"/>
</local:BordersPanel>
我很确定我遗漏了一些非常明显的东西,但这就是明显的东西,你越看它们,它们就越能躲避你......
顺便说一句,如果您认为有更好的方法来做我所做的事情(使用绑定、面板等),欢迎发表评论。:)
要非常清楚:在我使用之前:
<local:Border
Margin="0"
VerticalAlignment="top"
BlocksSize="LL50;ML200;RU"
Width="Auto" Height="10.8" HorizontalAlignment="Stretch" d:LayoutOverrides="Width"/>
<local:BinarySquares Margin="0,0,10,15" HorizontalAlignment="Right" VerticalAlignment="Bottom" d:LayoutOverrides="Width, Height"/>
<Grid Margin="8,14.8,8,24">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Canvas x:Name="pnl_Content5" Margin="0,0,0,0">
<Button Content="Button" HorizontalAlignment="Stretch" Canvas.Left="77" Canvas.Top="44"/>
</Canvas>
</ScrollViewer>
</Grid>
<local:Border
Margin="0"
VerticalAlignment="Bottom"
BlocksSize="LL50;ML200;RU;T"
Width="Auto" Height="10.8" HorizontalAlignment="Stretch"/>
每次使用面板时,我都会一遍又一遍地使用此代码。
显然我在前面的代码块中写的更短,更容易维护。(至少在我看来)这就是为什么我制作这个带有边框的自定义面板以避免重复代码。