2011-05-04 12 views
21

Dado el siguiente XAML, ¿cómo tengo el gridsplitter respetar la MinHeight dado a la tercera fila y tener el contenido de permanecer en el interior de mi ventana?parada Gridsplitter contenido se extiende más allá de la ventana

<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> 
+0

¿Necesita una solución puramente en XAML, o es la adición de código al código subyacente aceptables ? –

Respuesta

21

La forma en que su código es, esto no se puede hacer compañero. Esto se debe a cómo funciona el GridSplitter.

Unos pocos puntos

  • En realidad, se está respetando
  • Un GridSplitter siempre funcionará en directamente adyacentes filas/columnas su MinHeight, pero también lo es la solicitud de la GridSplitter a crecer siendo respetado, lo que resulta en la cuadrícula de crecimiento más grande que su ventana
  • Cuando se clasifican en Auto, una fila/columna siempre se ajustará en función de su contenido, no más grande, y no es menor
  • Por lo tanto, si un GridSplitter se intercala entre dos filas de tamaño/columnas *, entonces sería ld respetar implícitamente su MinHeight, ya que en realidad, no sería tocarlo

Usted tiene algunas soluciones

  1. Añadir otra fila en la tercera posición que es * tamaño, y tiene su borde en fila 3 con un RowSpan de 2 (por lo que la tercera fila es el que está siendo realmente cambiar de tamaño, y su cuarta fila no se toca. Aunque esto también tendrá efectos secundarios.
  2. Gestione una combinación de eventos DragEnter y PreviewMouseMove en el GridSplitter, controle el enfoque y cancele (e.Handled = true) el evento cuando se alcance un determinado tamaño.

Esto es lo que se me ocurre compañero, espero haber sido de alguna ayuda.

0

creé una clase divisor de cuadrícula personalizada que no permitirá que el separador de rejilla para ir por el borde de una ventana (ya sea la parte inferior o lateral).

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 

End Class

para usarlo en 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"/> 

Las propiedades personalizadas para configurar son los "SplitterDirection" y "MinimumDistanceFromEdge". Todo funciona como el divisor de rejilla base.

Este utiliza los eventos de ratón para determinar dónde en la ventana el usuario está arrastrando el divisor y se ocupa de los acontecimientos si se acercan demasiado cerca del borde.

0

he encontrado otra solución a este problema, aunque en un caso mucho más sencillo en el que sólo tenía dos columnas dentro de una ventana que quería cambiar el tamaño.

La solución que surgió (que se describe con más detalle aquí: https://stackoverflow.com/a/46924893/6481970) fue agregar devoluciones de eventos para cuándo se redimensionó la cuadrícula, cuándo se movió el GridSplitter y cuándo se redimensionó la ventana (para manejar el caso donde cambie el tamaño de la ventana para que ya no se ajuste al contenido porque la cuadrícula no se redimensiona automáticamente para ajustarse a la ventana más pequeña).

Aquí hay un código simplificado:

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# código subyacente:

C0.MaxWidth = Math.Min(ResizeGrid.ActualWidth, ActualWidth) - (C2.MinWidth + 5); 
Cuestiones relacionadas