回顧
上一篇,我們介紹了基本控件及控件的重要屬性和用法,我們本篇詳細介紹WPF中的幾種布局容器及每種布局容器的使用場景,當然這些都是本人在實際項目中的使用經驗,可能還存在錯誤之處,還請大家指出。
本文大綱
1、Grid
2、StackPanel
3、DockPanel
4、WrapPanel
Grid
1、Row和Column
我們下面來介紹Grid的行的用法,及我們在UI設計過程中需要注意的細節。
由於前面我們在第一章中已經介紹了基本的關於Grid的表格行和列的定義及相關屬性,為了防止大家遺忘,我們這里再次介紹下:
為了加深大家對Grid布局的印象,我們這里加入控件來展示效果。
下面在每個單元格都加入子控件
上面指定了控件在Grid表格中的哪一行那一列,如果我們的某個控件跨行或者跨列如何做呢?
關於跨行和跨列一樣,只不過將Grid.ColumnSpan換成Grid.RowSpan。
下面介紹,在Grid如何將控件設置為自適應寬度和高度,或者是固定寬度或固定高度時,應該注意的細節。
1、自適應區域:
2、頂部對齊或底部對齊
對於頂部對齊和底部對齊,相對來說都一樣。
3、左右對齊時:
4、下面來舉個例子,我們來如何分析,根據原型來使用Grid布局來達到要求和目標:
例如下圖:
我們以博客園為例,可能例子不太合適,但是如果我們想做一個博客園的桌面版,保持風格一致的情況下,如果我們使用Grid布局如何來布局呢?
A、有Logo圖片,上面還有設置等菜單,所以,我們可以吧這塊設置為二行,這樣比較容易區分頁面的布局和設置
B、下面有幾個二級菜單,新聞、博問等 一行
C、左側有網站分類。必須1列
D、右側有內容區。上面有區分首頁、精華、候選、新聞、關注等、1列
E、右側有找找看、還有最新新聞等 1列。
F、最下面,肯定還有狀態欄,如果我們開發桌面系統。1行
根據上面的分析,我們的Grid表格至少5行、3列
關於其他的設計,我們通過Grid表格的組合來進行控制。
下面我們就來實現下:
先設置大體布局如下:
關於上述布局的具體實現如下:
<Window x:Class="Samples.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="600" Width="800">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="50"/>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="1" Grid.ColumnSpan="2">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="何戈洲" Margin="5,0,0,0"/>
<Button Content="我的博客" Margin="5,0,0,0"/>
<Button Content="短消息" Margin="5,0,0,0"/>
<Button Content="設置" Margin="5,0,0,0"/>
<Button Content="退出" Margin="5,0,0,0"/>
</StackPanel>
</Grid>
<Grid Grid.Column="0" Grid.Row="1">
<Image Source="/Samples;Component/Images/logo_small.gif" />
</Grid>
<Grid Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="2">
<StackPanel Orientation="Horizontal">
<Button Margin="5,0,0,0">園子</Button>
<Button Margin="5,0,0,0">新聞</Button>
<Button Margin="5,0,0,0">博問</Button>
<Button Margin="5,0,0,0">閃存</Button>
<Button Margin="5,0,0,0">網摘</Button>
<Button Margin="5,0,0,0">招聘</Button>
<Button Margin="5,0,0,0">專題</Button>
<Button Margin="5,0,0,0">知識</Button>
</StackPanel>
</Grid>
<Grid Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="3">
<Image Source="/Samples;Component/Images/main.png" />
</Grid>
<Grid Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="4">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Margin="5,0,0,0">關於我們</Button>
<Button Margin="5,0,0,0">聯系我們</Button>
<Button Margin="5,0,0,0">廣告服務</Button>
<Button Margin="5,0,0,0">人才服務</Button>
<Button Margin="5,0,0,0">版權</Button>
</StackPanel>
</Grid>
</Grid>
</Window>
從上面的代碼可以看出來,非常的簡單,Grid特別適合軟件系統的整體布局,在實際的項目中通過Grid與其他的布局控件相結合一起完成頁面的整體布局。
StackPanel
StackPanel 適合水平或者垂直方向的布局,在上面的例子中我們大量的使用該種布局方式。適合局部區域的布局。比如博客園中的如下區域就可以采用StackPanel進行布局。
對於這類的固定的區域,我們可以不適用Grid來進行布局,使用StackPanel也可以達到目標。
我們來使用StackPanel來進行布局
<StackPanel Orientation="Vertical" VerticalAlignment="Stretch">
<GroupBox Header="網站分類" Height="Auto">
<StackPanel Orientation="Vertical">
<Button Content=".NET技術(16)"/>
<Button Content="編程語言(13)"/>
<Button Content="軟件設計(3)"/>
<Button Content="Web前端(16)"/>
<Button Content="軟件工程(26)"/>
</StackPanel>
</GroupBox>
<GroupBox Header="鏈接" Height="Auto">
<StackPanel Orientation="Vertical">
<Button Content="反饋和建議"/>
<Button Content="官方博客"/>
<Button Content="電子期刊" />
<Button Content="人才服務"/>
<Button Content="博客模板"/>
</StackPanel>
</GroupBox>
</StackPanel>運行效果如下:
與預期的效果相同,對於其他的模塊,我們也可以在局部,對於水平或者垂直方向要求進行布局的,我們都可以采用StackPanel來進行布局。
下面我們來看看橫向布局的例子:
我們通過表格中的使用對StackPanel的停靠定位,進而通過Stackpanel對內部的子控件的停靠方向設置,我們通過如下代碼實現上述效果:
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="何戈洲" Margin="5,0,0,0"/>
<Button Content="我的博客" Margin="5,0,0,0"/>
<Button Content="短消息" Margin="5,0,0,0"/>
<Button Content="設置" Margin="5,0,0,0"/>
<Button Content="退出" Margin="5,0,0,0"/>
</StackPanel>StackPanel在父容器中是右對齊的。
然后再StackPanel容器中,如果也采用內容右對齊,會有什么效果呢?
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="何戈洲" Margin="5,0,0,0" HorizontalAlignment="Right"/>
<Button Content="我的博客" Margin="5,0,0,0" HorizontalAlignment="Right"/>
<Button Content="短消息" Margin="5,0,0,0" HorizontalAlignment="Right"/>
<Button Content="設置" Margin="5,0,0,0" HorizontalAlignment="Right"/>
<Button Content="退出" Margin="5,0,0,0" HorizontalAlignment="Right"/>
</StackPanel>設置子控件的停靠方式時,不會起到任何作用,默認情況下,Stack的水平布局時,從左至右。
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" FlowDirection="RightToLeft">
<Button Content="何戈洲" Margin="5,0,0,0" HorizontalAlignment="Right"/>
<Button Content="我的博客" Margin="5,0,0,0" HorizontalAlignment="Right"/>
<Button Content="短消息" Margin="5,0,0,0" HorizontalAlignment="Right"/>
<Button Content="設置" Margin="5,0,0,0" HorizontalAlignment="Right"/>
<Button Content="退出" Margin="5,0,0,0" HorizontalAlignment="Right"/>
</StackPanel>修改了FlowDirection設置了StackPanel的方向后,所有的子控件,都是從右向左方向進行繪制和顯示,效果如下:
所以對於StackPanel我們基本上是用上述的屬性和對StackPanel的停靠方式進行設置后,即可滿足布局的要求。
DockPanel
DockPanel停靠容器,專門負責自適應窗口的布局,之前我們介紹了DockPanel的布局設置,這里再回顧下:
<DockPanel>
<StackPanel DockPanel.Dock="Top" Height="0">
</StackPanel>
<StackPanel DockPanel.Dock="Left" Height="0">
</StackPanel>
<StackPanel DockPanel.Dock="Bottom" Height="0">
</StackPanel>
<StackPanel DockPanel.Dock="Right" Orientation="Vertical" Width="200">
<GroupBox Header="最新新聞" Height="160">
<StackPanel Orientation="Vertical">
<Button Content="宅急送近日宣布降價搶"/>
<Button Content="騰訊聯手華為操盤四核手機"/>
<Button Content="Windows 8各版本區別與售價"/>
<Button Content="數方程將無線網絡帶寬提高一個數量級"/>
<Button Content="中移動:Lumia 920T將於11月上市"/>
<Button Content="Windows 8下一站:10月25日紐約"/>
</StackPanel>
</GroupBox>
<GroupBox Header="48小時閱讀排行榜" Height="160">
<StackPanel Orientation="Vertical">
<Button Content="子用戶-角色-權限-菜單 淺談:子賬戶設計方案"/>
<Button Content="網站已恢復正常,讓大家久等了"/>
<Button Content="拿什么拯救你,我的51Job簡歷?——UBB漏洞"/>
<Button Content="這些年我們沒用過的JS"/>
<Button Content="多少錢才可讓人重拾理想"/>
<Button Content="准備購買的Dell服務器的硬件配置"/>
</StackPanel>
</GroupBox>
</StackPanel>
<StackPanel ><Button Content=" 我鋪滿"/>
</StackPanel>
</DockPanel>上面的DockPanel在進行自適應布局時,默認最后的一個區域時默認填充,可以理解為fill。而必須制定其他的區域后,該設置才有效,所以,我們上面設置了top,left,bottom 占用的空間都是0,這樣,系統會將最后的一個子區域填充。
上面設置后的效果如下。
當然,這個頁面的整體,我們也可以采用DockPanel進行布局,布局的效果,完全可以達到上述效果,下面我們來使用DockPanel來對整體進行布局吧。
最終的代碼如下:
<DockPanel>
<StackPanel DockPanel.Dock="Top" Height="100">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="50"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid >
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" FlowDirection="RightToLeft">
<Button Content="何戈洲" Margin="5,0,0,0" HorizontalAlignment="Right"/>
<Button Content="我的博客" Margin="5,0,0,0" HorizontalAlignment="Right"/>
<Button Content="短消息" Margin="5,0,0,0" HorizontalAlignment="Right"/>
<Button Content="設置" Margin="5,0,0,0" HorizontalAlignment="Right"/>
<Button Content="退出" Margin="5,0,0,0" HorizontalAlignment="Right"/>
</StackPanel>
</Grid>
<Grid Grid.Row="1">
<Image Source="/Samples;Component/Images/logo_small.gif" HorizontalAlignment="Left"/>
</Grid>
<Grid Grid.Row="2">
<StackPanel Orientation="Horizontal">
<Button Margin="5,0,0,0">園子</Button>
<Button Margin="5,0,0,0">新聞</Button>
<Button Margin="5,0,0,0">博問</Button>
<Button Margin="5,0,0,0">閃存</Button>
<Button Margin="5,0,0,0">網摘</Button>
<Button Margin="5,0,0,0">招聘</Button>
<Button Margin="5,0,0,0">專題</Button>
<Button Margin="5,0,0,0">知識</Button>
</StackPanel>
</Grid>
</Grid>
</StackPanel>
<StackPanel DockPanel.Dock="Bottom" Height="30" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Margin="5,0,0,0">關於我們</Button>
<Button Margin="5,0,0,0">聯系我們</Button>
<Button Margin="5,0,0,0">廣告服務</Button>
<Button Margin="5,0,0,0">人才服務</Button>
<Button Margin="5,0,0,0">版權</Button>
</StackPanel>
<StackPanel DockPanel.Dock="Left" Width="150">
<StackPanel Orientation="Vertical" VerticalAlignment="Stretch">
<GroupBox Header="網站分類" Height="Auto">
<StackPanel Orientation="Vertical">
<Button Content=".NET技術(16)"/>
<Button Content="編程語言(13)"/>
<Button Content="軟件設計(3)"/>
<Button Content="Web前端(16)"/>
<Button Content="軟件工程(26)"/>
</StackPanel>
</GroupBox>
<GroupBox Header="鏈接" Height="Auto">
<StackPanel Orientation="Vertical">
<Button Content="反饋和建議"/>
<Button Content="官方博客"/>
<Button Content="電子期刊" />
<Button Content="人才服務"/>
<Button Content="博客模板"/>
</StackPanel>
</GroupBox>
</StackPanel>
</StackPanel>
<StackPanel DockPanel.Dock="Right" Orientation="Vertical" Width="200">
<GroupBox Header="最新新聞" Height="160">
<StackPanel Orientation="Vertical">
<Button Content="宅急送近日宣布降價搶"/>
<Button Content="騰訊聯手華為操盤四核手機"/>
<Button Content="Windows 8各版本區別與售價"/>
<Button Content="數方程將無線網絡帶寬提高一個數量級"/>
<Button Content="中移動:Lumia 920T將於11月上市"/>
<Button Content="Windows 8下一站:10月25日紐約"/>
</StackPanel>
</GroupBox>
<GroupBox Header="48小時閱讀排行榜" Height="160">
<StackPanel Orientation="Vertical">
<Button Content="子用戶-角色-權限-菜單 淺談:子賬戶設計方案"/>
<Button Content="網站已恢復正常,讓大家久等了"/>
<Button Content="拿什么拯救你,我的51Job簡歷?——UBB漏洞"/>
<Button Content="這些年我們沒用過的JS"/>
<Button Content="多少錢才可讓人重拾理想"/>
<Button Content="准備購買的Dell服務器的硬件配置"/>
</StackPanel>
</GroupBox>
</StackPanel>
<StackPanel >
<Button Content=" 我鋪滿"/>
</StackPanel>
</DockPanel>
運行上述代碼效果如下:
通過DockPanel完成對整體的布局,然后內部結合一些其他的布局控件,完成局部的細節的布局。
WrapPanel
WrapPanel容器我們也介紹過,該容器可以看做自動換行功能的StackPanel容器。下面我們就來分析下該容器的一般應用場景。
我們看到了windows8中的如下頁面,如果我們仿制該頁面的時候,其實我們可以采用wrappanel來實現自動的換行,下面我們來試試吧
最終代碼如下:
<Window x:Class="Samples.Window8Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window8Window" Height="600" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Label Content="開始" FontFamily="微軟雅黑" FontSize="30"/>
</Grid >
<Grid Grid.Row="1">
<WrapPanel Orientation="Horizontal" ItemHeight="100" ItemWidth="190">
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
<Image Source="/Samples;Component/Images/logo_small.gif" />
</WrapPanel>
</Grid>
</Grid>
</Window>
運行后,效果如下:
當然,我們的界面效果,還打不到美感,但是的確是自動換行。我們將水平方向,修改為垂直方向后,運行:
運行查看效果。
通過上面的簡單案例,我們基本上知道了wrapPanel的用法。
總結
通過上面的介紹和demo的演示,我們知道了如何在項目中什么情況下,使用什么樣的布局容器,通過實際的案例,我們更容易理解和掌握布局的模式。錯誤之處,還請大家反饋,我及時改正,謝謝!
參考出處:http://www.cnblogs.com/hegezhou_hot/archive/2012/10/23/2735874.html