1

私は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"/>

パネルを使用するたびに、このコードを何度も使用しています。

明らかに、前のコード ブロックで書いたものの方が短く、保守が容易です。(少なくとも私の意見では) そのため、コードの重複を避けるために、このカスタム パネルに境界線を付けました。

4

1 に答える 1

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>
于 2013-08-01T12:58:51.940 に答える