2011-05-04 128 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);