15

2つの行とそれらの間にスプリッターがあるグリッドレイアウトが必要です。行の高さは80ピクセル以上にする必要があります。

このコードはうまく機能します:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" MinHeight="80" />
        <RowDefinition Height="5" />
        <RowDefinition Height="*" MinHeight="80" />
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="0" Text="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}" />
    <GridSplitter Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Red" />
    <TextBlock Grid.Row="2" Text="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}" />
</Grid>

ただし、ユーザーがスプリッターを使用して手動で変更するまで、一番上の行に自動高さを設定したいと思います。だから私はこれにコードを変更しました:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" MinHeight="80" />
        <RowDefinition Height="5" />
        <RowDefinition Height="*" MinHeight="80" />
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="0" Text="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}" />
    <GridSplitter Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Red" />
    <TextBlock Grid.Row="2" Text="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}" />
</Grid>

そして問題があります。スプリッターは引き続き行の制約を満たしますが、スプリッターを低くドラッグしすぎると、一番上の行の高さが無限に増加し始めます。これにより、一番下の行がウィンドウの下の境界線より完全に下になります。

GridSplitterコードでReflectorを実行しましたが、行の高さがAutoまたはStarの場合、異なるロジックを使用することがわかりました。

どうすればそれを「修正」できるかという提案はありますか?

4

2 に答える 2

8

私はこの問題に何度か遭遇しました。GridSplitterがAutoでうまく機能しないように見えます。そうは言っても、私は潜在的な回避策を見つけました。

「スター係数」を使用して、GridLengthオブジェクトの値を指定できます。これは、問題の長さの乗数として機能します。

あなたの例では、星のままにしておきたい行を取得し、星の係数を非常に大きな数値に設定すると、その行は使用可能なすべてのスペースを占有します(他の行は強制的に最小の高さになります)。これは「auto」(最初の行の高さはコンテンツの高さによって決定されません)と同じ動作ではありませんが、近づく可能性があります。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" MinHeight="80" />
        <RowDefinition Height="5" />
        <RowDefinition Height="10000*" MinHeight="80" />
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="0" Text="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}" />
    <GridSplitter Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Red" />
    <TextBlock Grid.Row="2" Text="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}" />
</Grid>
于 2010-10-19T23:31:04.560 に答える
7

私はこの問題の回避策を開発しました。ポイントは、スプリッターをドラッグしているときに、一番上の行にMaxHeightを設定することです。ここにコードがあります:

public class FixedGridSplitter : GridSplitter
{
    private Grid grid;
    private RowDefinition definition1;
    private double savedMaxLength;

    #region static

    static FixedGridSplitter()
    {
        new GridSplitter();
        EventManager.RegisterClassHandler(typeof(FixedGridSplitter), Thumb.DragCompletedEvent, new DragCompletedEventHandler(FixedGridSplitter.OnDragCompleted));
        EventManager.RegisterClassHandler(typeof(FixedGridSplitter), Thumb.DragStartedEvent, new DragStartedEventHandler(FixedGridSplitter.OnDragStarted));
    }

    private static void OnDragStarted(object sender, DragStartedEventArgs e)
    {
        FixedGridSplitter splitter = (FixedGridSplitter)sender;
        splitter.OnDragStarted(e);
    }

    private static void OnDragCompleted(object sender, DragCompletedEventArgs e)
    {
        FixedGridSplitter splitter = (FixedGridSplitter)sender;
        splitter.OnDragCompleted(e);
    }

    #endregion

    private void OnDragStarted(DragStartedEventArgs sender)
    {            
        grid = Parent as Grid;
        if (grid == null)
            return;            
        int splitterIndex = (int)GetValue(Grid.RowProperty);
        definition1 = grid.RowDefinitions[splitterIndex - 1];
        RowDefinition definition2 = grid.RowDefinitions[splitterIndex + 1];
        savedMaxLength = definition1.MaxHeight;            

        double maxHeight = definition1.ActualHeight + definition2.ActualHeight - definition2.MinHeight;            
        definition1.MaxHeight = maxHeight;
    }

    private void OnDragCompleted(DragCompletedEventArgs sender)
    {
        definition1.MaxHeight = savedMaxLength;
        grid = null;
        definition1 = null;
    }
}

次に、GridSplitterをFixedGridSplitterに置き換えます。

注:このコードは一般的ではありません。列をサポートしておらず、一番下の行にMinHeightが指定されていることを前提としています。

于 2010-10-20T09:49:15.023 に答える