私は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"/>
パネルを使用するたびに、このコードを何度も使用しています。
明らかに、前のコード ブロックで書いたものの方が短く、保守が容易です。(少なくとも私の意見では) そのため、コードの重複を避けるために、このカスタム パネルに境界線を付けました。