前言
Grid是WPF中最強大的佈局容器,值得我們專門使用一個專題來了解Grid的使用。
使用
行列定義
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
</Grid>
行列寬高設置
行列的寬高有三種設置方式,我們按照推薦使用的順序進行說明:
- 自動尺寸設置(最常用,最推薦)
<RowDefinition Height="Auto"></RowDefinition>
- 按比例設置(自適應性好)
// 下面的高度是上面的二倍 <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="2*"></RowDefinition>
- 設置絕對寬高(死板,不靈活不推薦)
<RowDefinition Height="30"></RowDefinition>
可以拖動的分割條 GridSplitter
GridSplitter 使得用戶可以動態的調整Grid每行列的尺寸,比如電腦的資源管理器的左右佈局。
使用GridSplitter有下面一些指導原則:
- 使用GridSplitter的時候建議預留一行或者一列來放置GridSplitter對象,預留的這行列的寬高設置成Auto
- 每個GridSplitter拖動的時候,改變的是整行或者整列的尺寸,不是說GridSplitter放在哪個格子中就只改這個各自的尺寸,這點有點類似於拖動excel行列線
- 結合上面的特性,在使用GridSplitter的時候,最好讓他穿越整個行列,即設置RowSpan,如果不這樣做,那麼可拖動的範圍只有行那一點,但是效果還是整行或者整列移動
屬性說明:
- ShowPreview屬性。這個屬性決定了在拖動分割條的時候,尺寸是立即變化還是先顯示一個虛線的預覽
- DragIncrement屬性可以讓分割條的移動幅度更大,設置爲30,從平滑的拖動,變爲每30像素跳一下,類似於擋位的效果。
- Background屬性可以設置分割條的填充方式以改變分割條的外觀
設置GridSplitter的方式:
- 設置豎分割條需要將VerticalAlignment設置爲Stretch,Width設置爲一個固定值(讓這個分割條有點寬度以可見),HorizontalAlignment設置爲Center,由於這是屬性的默認值,所以不用顯式的指定
- 設置橫向分割條需要將HorizontalAlignment設置爲Stretch,Height設置爲固定值,VerticalAlignment設置爲Center,由於這是屬性的默認值,所以不用顯式的指定
舉例說明:
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="100"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition MinWidth="50"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0" Margin="3">Left</Button>
<Button Grid.Row="0" Grid.Column="2" Margin="3">Right</Button>
<Button Grid.Row="1" Grid.Column="0" Margin="3">Left</Button>
<Button Grid.Row="1" Grid.Column="2" Margin="3">Right</Button>
<GridSplitter Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" Width="3" VerticalAlignment="Stretch"
HorizontalAlignment="Center" ShowsPreview="False"></GridSplitter>
</Grid>
兩個Grid尺寸聯動 共享尺寸組
如果兩個Grid,其中一個Grid的一行或者一列尺寸改變的時候,另一個Grid的尺寸也得相應改變,就需要使用到共享尺寸組ShareSizeGroup
使用:
- 包含兩個Grid的外層控件必須設置 IsSharedSizeScope以確定共享尺寸範圍
- 共享的兩個行列的寬高需要設置 SharedSizeGroup = “labelName”
- ShareSizeGroup是在行列定義的時候指定
舉例說明:
<Grid Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="label1"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition MinWidth="50"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0" Margin="3">Left</Button>
<Button Grid.Row="0" Grid.Column="2" Margin="3">Right</Button>
<Button Grid.Row="1" Grid.Column="0" Margin="3">Left</Button>
<Button Grid.Row="1" Grid.Column="2" Margin="3">Right</Button>
<GridSplitter Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" Width="3" VerticalAlignment="Stretch"
HorizontalAlignment="Center" ShowsPreview="True" DragIncrement="30"></GridSplitter>
</Grid>
<Grid ShowGridLines="True" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="label1"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition MinWidth="50"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0" Margin="3">Left</Button>
<Button Grid.Row="0" Grid.Column="2" Margin="3">Right</Button>
<Button Grid.Row="1" Grid.Column="0" Margin="3">Left</Button>
<Button Grid.Row="1" Grid.Column="2" Margin="3">Right</Button>
</Grid>
</Grid>
注意事項和技巧
- 可以將Grid.ShowGridLine設置爲True來讓Grid顯示分割線,從而方便開發的時候觀察Grid面板的分割
- 佈局舍入。比如將99像素的Grid分成兩半,那麼因爲像素不能整分會導致模糊的問題。解決辦法是:
進行佈局舍入,內容會被對齊到最近的像素邊界,消除了模糊。<Grid UseLayoutRounding="True">
- 如果不給GridSplitter預留一行或者一列也可以使用,但是如果GridSplitter跟其他內容共享一個單元格,就要處理他們之間的相互關係使得其中的內容和GridSplitter不相互重疊