我对wpf很新。
我正在尝试制作一个带有一些奇特设计边框的自定义面板。 我得到了一切工作但只有我在自定义面板中只有一个控件。 如果我尝试添加多个,那么我会得到以下异常:
对象'BordersPanel'已经有一个孩子,无法添加'Button'。 '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"/>
每次使用面板时,我都会反复使用此代码。
显然,我在前面的代码块中编写的内容更短,更易于维护。 (最起码,我是这么想的) 这就是为什么我用边框制作这个自定义面板以避免重复代码。
答案 0 :(得分:1)
我找到了一个有效的解决方案。 这不是我想要的,但它足够接近它会做的。 我只是在BordersPanel实例中放置了一个网格声明。 我宁愿不必这样做,但我猜这样,它实际上允许我在面板内使用任何类型的布局。
<local:BordersPanel
BlocksSize="LL50;ML50;RU"
Margin="0">
<Grid>
<local:BinarySquares Margin="0,0,10,15" HorizontalAlignment="Right" VerticalAlignment="Bottom" d:LayoutOverrides="Width, Height"/>
<Button Content="Button" HorizontalAlignment="Stretch" Height="300"/>
</Grid>
</local:BordersPanel>