第一章已經簡單介紹過這個容器,這一節詳細介紹。
Grid一般是用表格(Grid.Row 和Grid.Column )的,比StackPanel更細致一些,但是,這麼玩很麻煩, 先橫著豎著定義一大堆,然後把元素指定其表格位置,即插入數據,和我們平常習慣的HTML表格不太一樣 ,甚至更麻煩了。
原因如下:Html空單元格要放占位符,這樣會放很多;Grid玩法則是用什麼元素就指定單元格位置, 不用的單元格默認是空,不用指定。另外,Grid單元格中的多個控件可以按照Z軸堆疊,這個順序是由控 件在xaml上的出現順序決定的。
Grid列寬的定義:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
第一種,固定長度——寬度不夠,會裁剪,不好用。單位pixel。
第二種,自動長度——自動匹配列中最長元素的寬度。
第三種,比例長度——*表示占用剩余的全部寬度;兩行都是*,將平分剩余寬度;像上面的一個2*, 一個*,表示前者2/3寬度。
單元格合並,1.4已經介紹過,這裡強調一點,雖然一個控件A跨越2個單元格,但是並未改變原來Grid 的所有單元格,也就是說,這是兩個對象Grid和控件A,互相不影響。那麼,另一個控件B仍然可以使用這 兩個單元格中的一個,最後根據A與B的先後出現順序會有重疊效果。這是不同於html單元格合並概念的。 這段話是我自己想的,多精辟啊,一針見血。終於對xaml有點感覺了。
接下來講的是多個Grid共享寬度組的技術。smaple講的是把grid放入ScrollViewer中,但是一旦滾動 ScollBar,grid的Title會跟著一起滾動,為了做到滾動時Title定住不動,要做兩個Grid:一個放Title ;另一個放主體,並嵌套進ScrollViewer中。這樣滾動問題解決了,另一個問題又出現了,就是兩個Grid 的字段對不齊,於是要使用shared-size組。
<DockPanel Grid.IsSharedSizeScope="True">
<Grid DockPanel.Dock="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Location" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Rank" />
<ColumnDefinition Width="Auto" />
//省略若干行代 碼
<Border Grid.Column="0" Grid.Row="0" BorderThickness="1"
Background="LightGray" BorderBrush="Gray">
<TextBlock>Title</TextBlock>
</Border>
<Border Grid.Column="1" Grid.Row="0" BorderThickness="1"
Background="LightGray" BorderBrush="Gray">
<TextBlock>Location</TextBlock>
</Border>
<Border Grid.Column="2" Grid.Row="0" BorderThickness="1"
Grid.ColumnSpan="2"
Background="LightGray" BorderBrush="Gray">
<TextBlock>Rank</TextBlock>
</Border>
<FrameworkElement Grid.Column="3"
Width="{DynamicResource {x:Static SystemParameters.ScrollWidthKey}}" />
</Grid>
<ScrollViewer>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Location" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Rank" />
</Grid.ColumnDefinitions>
//省略若干行代碼
</Grid>
</ScrollViewer>
</DockPanel>
首先,在DockPanel 設置共享:Grid.IsSharedSizeScope="True"。這樣做的目的是使得DockPanel外 的同名列不受影響。
DockPanel中兩個容器,Grid和ScrollViewer,前者設置標題,後者內嵌Grid,裝載內容行(紅色字體) 。
先說Grid,有4列,接著,設置第二列第三列為Shared-size Group,第一列寬度為*(自適用);第四列 的增加是因為width=*對SharedSize無效,所以增加這一列為ScrollBar占位:
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Location" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Rank" />
<ColumnDefinition Width="Auto" />
Rank跨占了2列,為了兼容多生成的第四列,
<Border Grid.Column="2" Grid.Row="0" BorderThickness="1"
Grid.ColumnSpan="2"
Background="LightGray" BorderBrush="Gray">
<TextBlock>Rank</TextBlock>
</Border>
接著,設置Grid第4列為滾動條寬度 ,於是因為Rank跨占了2列,所以Rank寬度為自己最大寬度+滾動 條寬度,這樣就保證了後面的都對齊了,從而前面第一列也對齊了:
<FrameworkElement Grid.Column="3"
Width="{DynamicResource {x:Static SystemParameters.ScrollWidthKey}}" />
再說ScrollViewer容器,在內嵌的Grid中設置Shared-size Group與第一個Grid中的列相對應:
<ColumnDefinition Width="Auto" SharedSizeGroup="Location" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Rank" />
注:這裡用到了DynamicResource ,而不是StaticResource,具體技術見第6章。
分析完畢。