前幾章用了相當大的篇幅研究有關WPF布局容器的復雜內容。在掌握了這些基礎知識后,就可以研究幾個完整的布局示例。通過研究完整的布局示例,可更好的理解各種WPF布局概念在實際窗口中的工作方式。
一、列設置
布局容器(如Grid面板)使得窗口創建整個布局結構變得非常容易。例如,分析如下顯示的窗口及設置。該窗口在一個表格結構中排列各個組件——標簽、文本框以及按鈕。

為創建這一表格,首先定義網格的行和列。行定義足夠簡單——只需要將每行的尺寸設置為所含內容的高度。這意味着所有行都將使用最大元素的高度,在該示例中,最大的元素是第三列中的Browse按鈕。
接下來需要創建列。第一列和最后一列的尺寸要適合其內容(分別是標簽文本和Browse按鈕)。中間列占用所有剩余空間,這意味着當窗口變大時,該列的尺寸會增加,這樣可有更大的空間顯示選擇的文件夾(如果希望拉伸不超過一定的最大寬度,在定義列時可使用MaxWidth屬性,就像對單個元素使用MaxWidth屬性一樣)。
現在已經具備了基本結構,接下來只需要在恰當的單元格中放置元素。然而,還需要仔細考慮邊距和對其方式。每個元素需要基本的邊距(3個單位較恰當)以在其周圍添加一些空間。此外,標簽和文本框的垂直方向上需要劇中,因為他們沒有Browse按鈕高。最后,文本框需要使用自動設置尺寸模式,這樣它會被拉伸以充滿整列。
示例完整的代碼如下所示:
<Window x:Class="LayoutDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid Margin="3,3,10,3"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"></ColumnDefinition> <ColumnDefinition Width="*"></ColumnDefinition> <ColumnDefinition Width="Auto"></ColumnDefinition> </Grid.ColumnDefinitions> <Label Grid.Row="0" Grid.Column="0" Margin="3" VerticalAlignment="Center">Home:</Label> <TextBox Grid.Row="0" Grid.Column="1" Margin="3" Height="Auto" VerticalAlignment="Center"></TextBox> <Button Grid.Row="0" Grid.Column="2" Margin="3" Padding="2">Browse</Button> <Label Grid.Row="1" Grid.Column="0" Margin="3" VerticalAlignment="Center">Network:</Label> <TextBox Grid.Row="1" Grid.Column="1" Margin="3" Height="Auto" VerticalAlignment="Center"></TextBox> <Button Grid.Row="1" Grid.Column="2" Margin="3" Padding="2">Browse</Button> <Label Grid.Row="2" Grid.Column="0" Margin="3" VerticalAlignment="Center">Web:</Label> <TextBox Grid.Row="2" Grid.Column="1" Margin="3" Height="Auto" VerticalAlignment="Center"></TextBox> <Button Grid.Row="2" Grid.Column="2" Margin="3" Padding="2">Browse</Button> <Label Grid.Row="3" Grid.Column="0" Margin="3" VerticalAlignment="Center">Secondary:</Label> <TextBox Grid.Row="3" Grid.Column="1" Margin="3" Height="Auto" VerticalAlignment="Center"></TextBox> <Button Grid.Row="3" Grid.Column="2" Margin="3" Padding="2">Browse</Button> </Grid> </Window>
一個不是非常明顯的事實是,因為使用了Grid控件,所以該窗口時非常靈活的。沒有任何一個元素——標簽、文本框以及按鈕——時通過硬編碼來定位和設置尺寸的。因此,可通過簡單地修改ColumnDefinition元素來快速改變整個網絡。甚至,如果添加了包含更長標簽文本的行(迫使第一列更寬),就會調整整個網格使其保持一致,包括已經添加的行。如果希望在兩行之間添加元素——例如,添加分割線以區分窗口的不同部分——可保持網格的列定義不變,但使用ColumnSpan屬性拉伸某個元素,使其覆蓋更大的區域。
二、動態內容
與上面的演示的列設置一樣,當修訂應用程序時,可方便地修改使用WPF布局容器的窗口並且可以很容易地時窗口適應對應用程序的修訂。這樣的靈活性不僅能使開發人員在設計時受益,而且如果需要顯示在運行時變化很大的內容,這樣是非常有用的。
一個例子是本地化文本——對於不同的區域,在用戶界面中顯示的文本需要翻譯成不同的語言。在老式的基於坐標的應用程序中,改變窗口中的文本會造成混亂,部分原因是少了英語文本翻譯成許多語言后會變得特別大。盡管允許改變元素的尺寸以適應更大的文本,但這樣做警察會使整體窗口失去平衡。
下圖演示WPF布局控件時如何聰明地解決這一問題。在這個示例中,用戶界面可選擇短文本和長文本。當使用長文本時,包含文本的按鈕會自動改變其尺寸,而對其他內容也會相應的調整位置。並且因此改變了尺寸的按鈕共享同一布局容器(在該例中是一個表格列),所以整個用戶界面都會改變尺寸。最終結果是所有按鈕保持一致的尺寸——最大按鈕的尺寸。

為實現這個效果,窗口使用一個具有兩行兩列的表格進行分割。左邊的列包含可改變大小的按鈕,而右邊的列包含文本框。底行用於放置Close按鈕,底行和頂行位於同一個表格中,從而可以根據頂行改變尺寸。
示例完整代碼如下所示:
<Window x:Class="LayoutDemo.LayoutWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="LayoutWindow" Height="300" Width="300"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"></ColumnDefinition> <ColumnDefinition Width="*"></ColumnDefinition> </Grid.ColumnDefinitions> <StackPanel Grid.Row="0" Grid.Column="0"> <Button Name="btnPrev" Margin="10,10,10,3">Prev</Button> <Button Name="btnNext" Margin="10,3,10,3">Next</Button> <CheckBox Name="chkLongText" Margin="10,10,10,10" Checked="chkLongText_Checked" Unchecked="chkLongText_UnChecked">Show Long Text</CheckBox> </StackPanel> <TextBox Grid.Row="0" Grid.Column="1" Margin="0,10,10,10" TextWrapping="Wrap" Grid.RowSpan="2"> This is a test that demonstrates how buttons adapt themselfes to fit the content they contain when they aren't explicitly sized.This behavior makes localization much easier. </TextBox> <Button Grid.Row="1" Grid.Column="0" Name="btnClose" Margin="10,3,10,10"> Close </Button> </Grid> </Window>
后台代碼如下所示:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace LayoutDemo { /// <summary> /// LayoutWindow.xaml 的交互邏輯 /// </summary> public partial class LayoutWindow : Window { public LayoutWindow() { InitializeComponent(); } private void chkLongText_Checked(object sender, RoutedEventArgs e) { this.btnPrev.Content = "<-Go to the Previous Window"; this.btnNext.Content = "Go to the Next Window ->"; } private void chkLongText_UnChecked(object sender, RoutedEventArgs e) { this.btnPrev.Content = "Prev"; this.btnNext.Content = "Next"; } } }
Visiblity屬性是UIEelement基類的一部分,因此放置於WPF窗口中的任何內容都支持該屬性。該屬性可使用三個值,它們來自System.Windows.Visiblity枚舉,如下表所示:

