StackPanel面板是最簡單的布局容器之一。該面板簡單地再單行或單列中以堆棧形式放置其子元素。
例如,分析下面的窗口,該窗口包含4個按鈕:
<Window x:Class="Layout.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Simple StackPanel" Height="300" Width="300"> <StackPanel> <Label>Button StackPanel</Label> <Button>Button1</Button> <Button>Button2</Button> <Button>Button3</Button> <Button>Button4</Button> </StackPanel> </Window>
下圖顯示了最終結果圖:
默認情況下,StackPanel面板按自上而下的順序排列元素,使每個元素的高度適合它的內容。在這個示例中,這意味着標簽和按鈕的大小剛好足夠適應他們內部包含的文本。所有元素都被拉伸到StackPanel面板的整個寬度,這也是窗口的寬度。如果加寬窗口,StackPanel面板也會變寬,並且按鈕也會拉伸自身以適應變化。
通過設置Orientation屬性,StackPanel面板也可用於水平排列元素:
<StackPanel Orientation="Horizontal">
現在,元素指定他們的最小寬度(足夠適合它們所包含的文本)並拉伸至容器面板的整個高度,根據窗口的當前大小,這可能導致一些元素不適應,如下圖所示:
一、布局屬性
盡管布局由容器決定,但子元素仍有一定的決定權。實際上,布局面板支持一小組布局屬性,以便與子元素結合使用,在下表中列出了布局屬性。
表 StackPanel布局屬性
所有這些屬性都是從FrameworkElement基類繼承而來,所以在WPF窗口中可使用的所有圖形小組件都支持這些屬性。
這些屬性列表就像它所么以偶包含的屬性一樣值得注意。如果查找熟悉的魚位置相關的屬性,例如Top屬性、Right屬性以及Location屬性,是不會找到他們的。這是因為大多數布局容器(Canvas控件除外)都使用自動布局,並未提供顯示定位元素的能力。
二、對齊方式
為理解這些屬性的工作原理,可進一步分析前面的簡單StackPanel面板。在這個示例中——有一個垂直方向的StackPanel面板——VerticalAlignment屬性不起作用,因為所有元素的高度都自動調整為剛好滿足各自需要。但HorizontalAlignment屬性非常重要,它決定了各個元素在行的什么位置。
通常,對於Label控件,HorizontalAlignment屬性的值默認為Left;對於Button控件,HorizontalAlignment屬性的值默認為Stretch。這也是為什么每個按鈕的寬度被調整為整列的寬度的原因所在。但可以改變這些細節:
<Window x:Class="Layout.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Simple StackPanel" Height="300" Width="300"> <StackPanel > <Label HorizontalAlignment="Center">Button StackPanel</Label> <Button HorizontalAlignment="Left">Button1</Button> <Button HorizontalAlignment="Right">Button2</Button> <Button>Button3</Button> <Button>Button4</Button> </StackPanel> </Window>
最終顯示結果如下所示:
三、邊距
在StackPanel示例中,在當前情況下存在一個明顯的問題。設計良好的窗口不只是包含元素——還應當在元素之間包含一定的額外空間。為了添加而外的空間並使StackPanel面板示例中的按鈕不那么緊密,可為控件設置邊距。
當設置邊距時,可為所有邊設置相同的寬度,如下所示:
<Button Margin="5">Button3</Button>
相應地,也可為控件的每個邊以左、上、右、下的順序設置不同的寬度,如下所示:
<Button Margin="5,10,10,5">Button4</Button>
在代碼中,是代碼中使用Thickness進行設置:
cmd.Margin=new Thickness(5);
為得到正確的控件邊距,需要采用一些藝術手段,因為需要考慮相鄰控件邊距設置的相互影響。例如,如果兩個按鈕堆在一起,位於最高處的按鈕的底部邊距設置為5,而下面按鈕的頂部邊距也設置為5,那么這兩個按鈕之間就有10個單位的空間。
理想情況下,能盡可能始終如一地保持不同的邊距設置,避免為不同的邊設置不同的值。例如,在StackPanel示例中,為按鈕和面板本身設置相同的邊距比較合適。如下所示:
<Window x:Class="Layout.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Simple StackPanel" Height="300" Width="300"> <StackPanel Margin="3" > <Label Margin="3" HorizontalAlignment="Center">Button StackPanel</Label> <Button Margin="3" HorizontalAlignment="Left">Button1</Button> <Button Margin="3" HorizontalAlignment="Right">Button2</Button> <Button Margin="3">Button3</Button> <Button Margin="3">Button4</Button> </StackPanel> </Window>
最終顯示效果如下所示:
四、最小尺寸、最大尺寸以及顯示的尺寸設置
每個元素都提供了Height和Width屬性,用來顯示地指定元素大小。但這種設置一般不是一個號主意。相反,如果必要,應當使用最大尺寸和最小尺寸屬性,將控件限制在正確的范圍內。
如下代碼所示:
<Window x:Class="Layout.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Simple StackPanel" Height="300" Width="300"> <StackPanel Margin="3" > <Label Margin="3" HorizontalAlignment="Center">Button StackPanel</Label> <Button Margin="3" MaxWidth="200" MinWidth="100">Button1</Button> <Button Margin="3" MaxWidth="200" MinWidth="100">Button2</Button> <Button Margin="3" MaxWidth="200" MinWidth="100">Button3</Button> <Button Margin="3" MaxWidth="200" MinWidth="100">Button4</Button> </StackPanel> </Window>
運行效果如下圖所示已經修改窗體大小
當StackPanel調整按鈕的尺寸時,需要考慮以下部分信息:
- 最小尺寸。每個按鈕的尺寸始終不能小於最小尺寸
- 最大尺寸。每個按鈕的尺寸始終不能超過最大尺寸(除非執行錯誤操作,使最大尺寸比最小尺寸還小)
- 內容。如果按鈕中的內容需要更大的寬度,StackPanel容器會嘗試擴展按鈕(可以通過檢查DesiredSized屬性確定所需的按鈕大小,該屬性返回最小寬度或內容的寬度,返回兩者中較大的那個)。
- 容器大小。如果最小寬度大於StackPanel面板的寬度,按鈕的一部分將被剪裁掉。否則,不允許按鈕比StackPanel面板更寬,即使不能適合按鈕表面的所有文本。
- 水平對齊方式。因為默認情況下按鈕的HorizontalAlignment屬性設置為Stretch,所以StackPanel面板嘗試反映按鈕所期望的尺寸(以適合其內容)以及對齊方式的設置。
理解這個過程的關鍵在於,要認識到最小尺寸和最大尺寸設置了絕對界限。在這個界限內,StackPanel面板嘗試反映按鈕所期望的尺寸以及對齊方式的設置。通過調整上面示例的寬度,查看窗口中的按鈕變化情況。
五、Border控件
Border控件不是布局面板,而是非常便於使用的元素,經常與布局面板一起使用。
Border類非常簡單。它只能包含一段嵌套內容(通常是布局面板),並為其添加背景或在其周圍添加邊框。為了深入理解Border控件,只需要賬務下表中列出的屬性就可以。
下面是一個具有輕微圓角效果的簡單邊框,該邊框位於一組按鈕的周圍,這組按鈕包含在一個StackPanel面板中:
<Window x:Class="Layout.BorderWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="BorderWindow" Height="300" Width="300"> <Border Margin="5" Padding="5" Background="LightGoldenrodYellow" BorderBrush="SteelBlue" BorderThickness="3,5,3,5" CornerRadius="3" VerticalAlignment="Top"> <StackPanel> <Button Margin="3">Button1</Button> <Button Margin="3">Button2</Button> <Button Margin="3">Button3</Button> <Button Margin="3">Button4</Button> </StackPanel> </Border> </Window>
運行效果圖下圖所示: