24

以下のXAMLを前提として、グリッドスプリッターに3行目に指定されたMinHeightを尊重させ、コンテンツをウィンドウ内に残しておくにはどうすればよいですか?

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition MinHeight="40" />
    </Grid.RowDefinitions>
    <Expander Grid.Row="0" ExpandDirection="Down" VerticalAlignment="Top">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" MinHeight="40" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Border Grid.Row="0" MinHeight="100" Background="Black" />
            <GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Background="LightBlue" ResizeBehavior="PreviousAndCurrent" />
        </Grid>
    </Expander>
    <Expander Grid.Row="1" ExpandDirection="Down" VerticalAlignment="Top">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" MinHeight="40" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Border Grid.Row="0" MinHeight="100" Background="Black" />
            <GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Background="LightBlue" ResizeBehavior="PreviousAndCurrent" />
        </Grid>
    </Expander>
    <Border DockPanel.Dock="Bottom"  Grid.Row="2" Background="Lime" MinHeight="30" >
        <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DockPanel},Path=ActualHeight,StringFormat={}{0:f0}}" />
    </Border>
</Grid>
4

3 に答える 3

23

あなたのコードがそうであるように、これは仲間にすることはできません。これは、GridSplitterの動作によるものです。

いくつかのポイント

  • GridSplitterは、常に直接隣接する行/列で機能します
  • 実際には、MinHeightは尊重されていますが、GridSplitterの成長要求も尊重されているため、グリッドはウィンドウよりも大きくなります。
  • [自動]にサイズ変更すると、行/列は常にその内容に応じてサイズ変更され、大きくも小さくもなりません
  • したがって、GridSplitterが2つの*サイズの行/列の間に挟まれている場合、実際にはMinHeightに触れないため、暗黙的にMinHeightを尊重します。

いくつかの解決策があります

  1. *サイズの3番目の位置に別の行を追加し、行3の境界線をRowSpan 2にします(したがって、3番目の行は実際にサイズ変更され、4番目の行は変更されません。これも副作用。
  2. GridSplitterでDragEnterイベントとPreviewMouseMoveイベントの混合を処理し、フォーカスを追跡し、特定のサイズに達したときにイベントをキャンセルします(e.Handled = true)。

これは私が仲間について考えることができるものです、私がいくつかの助けになったことを願っています。

于 2011-06-23T22:19:39.707 に答える
3

グリッドスプリッターがウィンドウの端(下部または側面)から外れないようにするカスタムグリッドスプリッタークラスを作成しました。

Public Class CustomGridSplitter
Inherits GridSplitter

Public Enum SplitterDirectionEnum
    Horizontal
    Vertical
End Enum

Public Property SplitterDirection As SplitterDirectionEnum
Public Property MinimumDistanceFromEdge As Integer

Private _originPoint As Point

Private Sub customSplitter_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles MyBase.MouseDown
    _originPoint = e.GetPosition(Window.GetWindow(Me))
End Sub

Private Sub customSplitter_PreviewMouseMove(sender As Object, e As MouseEventArgs) Handles MyBase.PreviewMouseMove

    If e.LeftButton = MouseButtonState.Pressed Then
        Dim pwindow As Window = Window.GetWindow(Me)
        Dim newPoint As Point = e.GetPosition(pwindow)

        If SplitterDirection = SplitterDirectionEnum.Horizontal Then
            If newPoint.Y >= _originPoint.Y Then
                If newPoint.Y >= pwindow.ActualHeight - MinimumDistanceFromEdge Then
                    e.Handled = True
                End If
            Else
                If newPoint.Y > pwindow.ActualHeight - (MinimumDistanceFromEdge + 2) Then
                    e.Handled = True
                End If
            End If
        Else
            If newPoint.X >= _originPoint.X Then
                If newPoint.X >= pwindow.ActualWidth - MinimumDistanceFromEdge Then
                    e.Handled = True
                End If
            Else
                If newPoint.X > pwindow.ActualWidth - (MinimumDistanceFromEdge + 2) Then
                    e.Handled = True
                End If
            End If
        End If


        _originPoint = newPoint
    End If
End Sub

エンドクラス

XAMLで使用するには:

<CustomGridSplitter SplitterDirection="Vertical" MinimumDistanceFromEdge="100" x:Name="splitterCenter" ResizeDirection="Columns" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Stretch" Width="2" Margin="2,0,2,0"/>

設定するカスタムプロパティは、「SplitterDirection」と「MinimumDistanceFromEdge」です。すべてがベースグリッドスプリッターのように機能します。

これは、マウスイベントを使用して、ウィンドウ内のどこでユーザーがスプリッターをドラッグしているかを判別し、イベントがエッジに近づきすぎた場合にイベントを処理します。

于 2016-05-03T13:37:35.010 に答える
-1

この問題の別の解決策を見つけましたが、サイズを変更したいウィンドウ内に2つの列があるという、はるかに単純なケースです。

私が思いついた解決策(詳細はhttps://stackoverflow.com/a/46924893/6481970)は、グリッドのサイズが変更されたとき、GridSplitterが移動したとき、ウィンドウが移動したときのイベントコールバックを追加することでした。サイズ変更(グリッドが小さいウィンドウに合わせて自動的にサイズ変更されないため、コンテンツに合わせないようにウィンドウのサイズを変更する場合を処理するため)。

簡略化したコードを次に示します。

XAML:

<Grid x:Name="ResizeGrid" SizeChanged="ResizeGrid_SizeChanged">
    <Grid.ColumnDefinitions>
        <ColumnDefinition x:Name="C0" Width="150" MinWidth="50" />
        <ColumnDefinition Width="5" />
        <ColumnDefinition x:Name="C2" Width="*" MinWidth="50" />
    </Grid.ColumnDefinitions>

    <Grid Grid.Column="0" Background="Green" />
    <GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" DragCompleted="GridSplitter_DragCompleted" />
    <Grid Grid.Column="2" Background="Red" />
</Grid>

C#の背後にあるコード:

C0.MaxWidth = Math.Min(ResizeGrid.ActualWidth, ActualWidth) - (C2.MinWidth + 5);
于 2017-10-25T06:01:03.253 に答える