學習WPF——WPF布局——了解布局容器


WPF布局工作內部原理
WPF渲染布局時主要執行了兩個工作:測量和排列
測量階段,容器遍歷所有子元素,並詢問子元素所期望的尺寸
排列階段,容器在合適的位置放置子元素,並設置元素的最終尺寸
這是一個遞歸的過程,界面中任何一個容器元素都會被遍歷到
WPF布局容器的繼承機制
DispatcherObject
WPF應用程序使用單線程親和模型(STA:Single-Thread Affinity),這意味着整個用戶界面都為單個線程擁有,同時也意味着從另一個線程與用戶界面元素交互是不安全的,但有很多情況下需要從其他線程訪問界面元素,那怎么辦呢?WPF有一個統一的機制來處理這些問題,這個我們在后續的章節涉及到之后再深入講解,大家只要知道,只要繼承DispatcherObject的界面元素就能很方便的處理這些問題就好啦
DependencyObject
WPF的屬性的實現機制和Winform程序有很大的差異,Winform控件的屬性很多是通過繼承機制得來的,在你認為超過90%的用戶界面控件的屬性通常留其初始值時,為每一個屬性存儲一個字段將是對內存的巨大的浪費。 DependencyObject(依賴屬性)解決了僅僅存儲改變了屬性的問題。默認值在依賴屬性中只存儲一次。這只是依賴項屬性的一個好處,還有其他好處我們以后再聊。
Visual
WPF程序中的所有可視化元素基本上都是繼承自Visual類,這個類封裝了繪圖指令和附加的繪圖細節(比如透明和裁剪等),如果你不想用WPF的界面元素,更希望使用一個輕量級的繪圖API,那么你可以直接對Visual對象進行編程
UIElement
UIElement為可視元素增加了更多的功能,比如布局、輸入、焦點、事件、命令等,
FrameworkElement
對UIElement進行了增強,比如UIElement為布局機制設置了基礎,但FrameworkElement提供了支持它的重要屬性,如:HorizontalAlignment、Margin等屬性
Panel
是所有布局元素的基類,所有布局元素都派生自此類型,它用於放置和排列WPF元素,這個抽象類只包含三個公共屬性:Background、Children、IsItemHost( IsItemHost標志着控件是不是類似TreeView、ListView這樣的控件)
布局屬性
布局容器內的子元素對自身的大小、位置有一定的決定權
子元素可以設置自身的布局屬性來調整自己的位置和大小
HorizontalAlignment
水平對齊方式
VerticalAlignment
垂直對其方式
Margin
在元素周圍添加一定的空隙
MinWidth/MinHeight
最小尺寸
MaxWidth/MaxHeight
最大尺寸
Width/Height
尺寸屬性

Grid行與列的尺寸

如果要顯式的設置Grid的行和列的尺寸,只要設置具體的值即可:
<RowDefinition Height="30"></RowDefinition>
但很多時候需要讓行或者列自適應高度或者寬度,那么可以給相應的屬性設置Auto值:
<RowDefinition Height="Auto"></RowDefinition>
還有的時候需要按比例設置行和列的高度或者寬度,那么可以使用*通配符:
<RowDefinition Height="*"></RowDefinition> 
<RowDefinition Height="2*"></RowDefinition>

Grid跨行與跨列

當希望Grid內的元素跨越多行或者多列的時候,可以使用RowSpan或ColumnSpan來實現
<Button Grid.RowSpan="2" Grid.ColumnSpan="2"></Button>

GridSpliter分割窗口

經常有這樣的需求,需要通過拖動的方式改變一個窗口內部區域的大小
GridSpliter能很好的滿足這種需求,
在增加一行或一列的大小的同時,減小其他行或者列的大小(因為一個窗口的區域大小是固定的,此消彼長)
注意HorizontalAlignment屬性必須設置

共享尺寸

假設我們有兩個Grid,每個Grid都有兩行,而且兩行的高度都設置為auto,
我們希望這兩個Grid的行高保持一致
也就是說某一個grid的行高根據自身的內容變化之后,另一個grid的行高也跟着變化
以往實現這樣的需求,一定要編寫C#代碼才行,現在我們可以使用WPF的共享尺寸特性來實現這一需求
(大家可以看到,第二個grid里的button我沒有設置高度,但它也變高了)

均衡表格UniformGrid

當你不希望使用Grid復雜的行列設置,只希望把元素“平均”放置到界面上,
那么你可以使用UniformGrid來實現這樣的需求

Z軸順序

我們知道在Canvas布局容器中,如果位置重疊,后設置的元素會蓋住先設置的元素,
如果想打破這種規定,那么可以使用ZIndex屬性:

修改記錄

2014-12-26:編寫前兩部分內容
2014-12-29:修改第二節的內容,增加最后兩節的內容
2014-12-30:完成剩余的內容
2015-01-05:修改了幾個文字

參考資料

《Pro WPF 4.5 in C# 4th Edition》
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM