2011-05-04 53 views
21

鉴于下面的XAML,我如何让网格分离器尊重MinHeight给第三行并让内容保留在窗口内?停止Gridsplitter将窗口内容拉伸超过窗口

<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

你在XAML纯粹需要一种解决方案,或将代码添加到代码隐藏可接受? – 2011-06-23 17:37:34

回答

21

您的代码的方式,这是不能做配偶。这是由于GridSplitter的工作原理。

的几点

  • 一个GridSplitter将始终工作在直接相邻的行/列
  • 在现实中,你的了minHeight被尊重,但这样是GridSplitter的要求增长得到尊重,这导致网格的长度大于窗口的大小
  • 当大小设置为自动时,行/列总是根据其内容调整大小,而不是更大,并且不会更小
  • 因此,如果GridSplitter夹在两个*大小的行/列之间,那么它呢LD隐含尊重你了minHeight,因为在现实中,它不会被触及它

你有几个解决方案

  1. 添加在第三个位置,这是*大小的另一行,并在有你的边界第3行的RowSpan为2(所以第3行是真正调整大小的行,而第4行没有被触及。虽然这也会有副作用。
  2. 在GridSplitter上处理DragEnter和PreviewMouseMove事件的混合,跟踪焦点并在达到特定大小时取消事件(e.Handled = true)。

这是我能想到的队友,希望我有一些帮助。

0

我创建了一个自定义网格分离器类,它不允许网格分离器离开窗口的边缘(底部或侧面)。

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”。一切都像基本网格分离器一样工作。

这使用鼠标事件来确定用户在窗口中的哪个位置拖动拆分器,并在事件过于接近边缘时处理这些事件。

0

我发现了另一个解决这个问题的方法,虽然在一个更简单的情况下,我只想在调整窗口内放置两列。

我想到的解决方案(在此处详细描述: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);