佈局原則
- 空間的尺寸可以自適應。(要實現這樣的效果需要不顯式的指定控件尺寸,而是設置控件尺寸的最大最小值)
- 不設置絕對定位,使用相對定位(比如使用margin就是相對定位而非絕對座標)
- 佈局控件能爲子控件合理分配尺寸
- 佈局控件可以嵌套佈局控件
類關係
佈局控件都派生自Panel(類關係可以在之前的文章中找到)。Panel是一個抽象類,提供了一些公共屬性。
注意1:當我們在實際工作中,會出現點擊區域過小或者需要擴大點擊區域的問題,比如一個大的Grid中居中放置一個圖片,掛載點擊事件之後,有時候會遇到只有圖片的範圍才能點擊的問題,其實解決辦法就在上圖中,Background爲空值不接收點擊事件,只需要將背景設置爲透明即可。
注意2:Children中還可以防止Panel達到嵌套佈局的作用
IsItemHost屬性比較複雜我們在之後的講解中再深入討論。
佈局控件
常用
- StackPanel
- WrapPanel 可以換行
- DockPanel
- Grid
- UniformGrid 所有的單元格都是同樣的尺寸,比如做掃雷
- Canvas
不常用
- TabPanel 多個選項卡
- ToolbarPanel 工具欄的按鈕
- ToolbarOverflowPanel 工具欄溢出菜單
- VirtualizingStackPanel 降低開銷
- InkCanvas 手寫筆
StackPanel
- 默認爲縱向
- 可以使用VerticalAlignment 和 HorizontalAlignment,他們倆默認的值隨着不同的控件調整,比如Label的默認值爲Left,Button的默認值爲Stretch,注意對於垂直排列的容器,VerticalAlignment不起作用,橫向容器 HorizontalAlignment 不起作用。縱向容器,子控件的高度自動調整爲子空間需要的合適高度。
- 可以使用Margin屬性讓子控件之間保持一定的距離
Border
Border不是佈局元素,但是可以套在佈局元素外面實現邊框。他的屬性有:
舉個例子:
<Border Height="80" Width="80" Padding="5" Background="LightYellow" BorderBrush="SteelBlue" BorderThickness="3 5 3 5" CornerRadius="3" HorizontalAlignment="Left" Margin="370.118,253,0,0" VerticalAlignment="Top" >
<StackPanel>
<Button Margin="3"></Button>
<Button Margin="3"></Button>
<Button Margin="3"></Button>
</StackPanel>
</Border>
WrapPanel
WrapPanel可以實現類似於工具欄那種排列的控件,用於控制局部的佈局細節。他的默認方向是橫向。他的尺寸是由內部排列的控件決定的。當剩餘寬度或者高度不足顯示下一個控件的時候,折行。注意,WrapPanel所實現的效果是唯一一個不能通過Grid實現的佈局效果。
上圖告訴我們,對於橫向的WrapPanel來說,可以設置VerticalAlignment來實現控件的靠上靠下或者拉伸。
DockPanel
DockPanel可以讓子元素停靠在容器的每個邊,實現的效果是下面的效果。
注意:
- 停靠的順序看聲明的順序
- 可以設置最後一個控件充滿剩餘空間,只需要把DockPanel的LastChildFill屬性設置爲True即可
Grid
Grid是十分重要的佈局控件,我們將用一個專題來專門講解Grid
UniformGrid
創建簡單平均分配的表格。比如在創建掃雷頁面的時候使用。使用Rows和Columns來控制行數和列數。
<UniformGrid Rows="2" Columns="2" HorizontalAlignment="Left" Height="92.5" Margin="43.796,391.5,0,0" VerticalAlignment="Top" Width="118.795">
<Button>1</Button>
<Button>2</Button>
<Button>3</Button>
<Button>4</Button>
</UniformGrid>
它是一個特殊的佈局工具,用於在規則的網格中快速的佈局,在實際的開發中並不常用。
Canvas
- Canvas的特點是允許使用精確的座標放置元素
- Canvas的優點是這個佈局控件沒有任何默認的佈局邏輯,我們可以精確的控制每一個控件的佈局邏輯
- Canvas.Left 和 Canvas.Right不能同時使用 同樣的 Canvas.Top 和 Canvas.Bottom也不能同時使用。
<Canvas> <Button Canvas.Left="10" Canvas.Top="10">(10, 10)</Button> </Canvas>
- 使用Canvas.ZIndex來調整Z序,Z序默認是0,Z序相同的控件後聲明的在上面,Z序也可以設置爲負數
InkCanvas
適用於手寫筆輸入的控件
-
InkCanvas 派生自 FrameworkElement類
<InkCanvas Background="LightYellow"/>
-
所有的子元素都保存在Children集合中
-
所有的用戶輸入都保存在Strokes集合中
-
輸入模式InkCanvas.EditingMode的屬性設置
注意事項和技巧
- 合理利用控件尺寸的最大值和最小值,用最小值來防止控件被裁剪,用最大值來防止控件超出範圍。
- 佈局容器都不能滾動,需要滾動的時候需要使用ScrollViewer
- 容器的背景不是空值的時候不能接受鼠標點擊事件
- IDE可以看到嵌套的元素樹,在Blend中,是在視圖-其他窗口-對象和時間線 窗口。在VS中,是視圖-其他窗口-文檔大綱窗口。
- 除了Canvas的其他佈局控件的默認ClipToBounds屬性都是設置爲true的(這個屬性標識超出佈局控件之後是否裁剪),這就導致瞭如果想讓Canvas中的控件超出之後在邊緣出裁切,就需要設置Canvas的ClipToBounds屬性爲true