6

1 つのコントロールを塗りつぶし、残りをドッキングするように設定したレイアウトを作成する論理的でシンプルな方法が必要です。私は使用できます:

<DockPanel LastChildFill="True">
  <Button Content="3" DockPanel.Dock="Bottom" />
  <Button Content="2" DockPanel.Dock="Bottom" />
  <Button Content="1" />
</DockPanel>

しかし、それを使用するのはあまり直感的ではありません。次のようにすることもできます。

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="*" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
  <Button Content="1" Grid.Row="0" />
  <Button Content="2" Grid.Row="1" />
  <Button Content="3" Grid.Row="2" />
</Grid>

しかし、xamlもかなりたくさんあります。私が本当に欲しいのは次のようなものです:

<StackPanel Fill="None|First|Last">
  <Button Content="1" />
  <Button Content="2" />
  <Button Content="3" />
</StackPanel>

DockPanel のようにアイテムを逆にする必要がなく、Grid のように固定数の行と添付プロパティを使用せずに、これをどのように達成できますか?

4

3 に答える 3

3

さまざまなドッキング ルールを使用して、いつでも独自のパネルを作成できます。標準の DockPanel 実装 (フレームワーク ソースで利用可能 - それほど複雑には見えません) を使用して、好みのルールで同様のものを作成できます。DockPanel から派生し、ArrangeOverride をオーバーライドするクラスを作成できる場合もあります。

しかし、個人的にはドック パネルを使用します。これは、どのメンバーがフィルになるかについてのルールが気に入らないことを除いて、まさにあなたが望むことを行います。

IME グリッドには、行を挿入/削除する場合、行番号を際限なく調整する必要があるという点で、メンテナンスに関する恐ろしい問題があります。その点では、DockPanel の方がはるかに簡単です。

アップデート:

どうぞ、私はあなたがこれを自分で行う喜びを否定しました-これはフレームワークソースのカットダウン/リバースバージョンです:

public class BottomDockingPanel : DockPanel
{
    protected override Size ArrangeOverride(Size arrangeSize)
    {
        UIElementCollection children = InternalChildren;
        int totalChildrenCount = children.Count;

        double accumulatedBottom = 0;

        for (int i = totalChildrenCount-1; i >=0 ; --i)
        {
            UIElement child = children[i];
            if (child == null) { continue; }

            Size childDesiredSize = child.DesiredSize;
            Rect rcChild = new Rect(
                0,
                0,
                Math.Max(0.0, arrangeSize.Width - (0 + (double)0)),
                Math.Max(0.0, arrangeSize.Height - (0 + accumulatedBottom)));

            if (i > 0)
            {
                accumulatedBottom += childDesiredSize.Height;
                rcChild.Y = Math.Max(0.0, arrangeSize.Height - accumulatedBottom);
                rcChild.Height = childDesiredSize.Height;
            }

            child.Arrange(rcChild);
        }
        return (arrangeSize);
    }
}
于 2011-02-28T14:13:59.803 に答える
1

内部に StackPanel がある DockPanel を使用できます。「メイン」コンテンツは最初ではなく最後に表示されますが、少なくとも下部のコンテンツは XAML で論理的な順序で表示されます。埋められたコンテンツを最後にしたい場合は、これが最も簡単な方法です。

<DockPanel LastChildFill="True">
  <StackPanel DockPanel.Dock="Bottom">
    <Button Content="Bottom 1" />
    <Button Content="Bottom 2" />
    <Button Content="Bottom 3" />
  </StackPanel>
  <Button Content="Main" />
</DockPanel>

または、すべて (塗りつぶされたコンテンツを含む) を画面に表示されるのと同じ順序で XAML に表示する場合は、2 行の Grid と 2 行目の StackPanel を使用できます。ご指摘のとおり、グリッドにはかなりの量の XAML が必要ですが、ネストされた StackPanel を使用すると、新しい項目ごとに RowDefinition と Grid.Row を追加する必要がなくなります。

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="*" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
  <Button Grid.Row="0" Content="Main" />
  <StackPanel Grid.Row="1">
    <Button Content="Bottom 1" />
    <Button Content="Bottom 2" />
    <Button Content="Bottom 3" />
  </StackPanel>
</Grid>
于 2011-02-28T14:35:12.720 に答える
0

WPF には、これをすぐにサポートするようなパネルはありません。この特定の動作が必要な場合は、独自のパネルを作成することもできますが、これは非常にカスタムであり、それほど頻繁に必要とされないため、そうすることはお勧めしません (MiddleChildFill のような動作を持つパネルが必要な場合はどうでしょうか?その場合のあなた自身のパネルも?)。

通常、この種のレイアウトはGrid(あなたが述べたように)を使用して実現されます。はい、これは非常に冗長な構文 (このGridようなヘルパーを使用して単純化できます)を持っているのは事実ですが、最も柔軟性が高くなります。そして、結局のところ、これが重要です。

于 2011-02-28T14:21:57.880 に答える