私はwpfにかなり慣れていません。
派手なデザインの境界線を持つカスタム パネルを作成しようとしています。カスタムパネルにコントロールが1つしかない場合に限り、すべてが機能しました。複数追加しようとすると、次の例外が発生します。
オブジェクト 'BordersPanel' には既に子があり、'Button' を追加できません。「BordersPanel」は、子を 1 つだけ受け入れることができます。
ネットで解決策を探すのに多くの時間を費やしましたが、今のところ何もありません。だから私はコミュニティに助けを求めています。
パネル スタイル:
<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"/>
パネルを使用するたびに、このコードを何度も使用しています。
明らかに、前のコード ブロックで書いたものの方が短く、保守が容易です。(少なくとも私の意見では) そのため、コードの重複を避けるために、このカスタム パネルに境界線を付けました。