您的位置:首页 > 其它

使用Grid来对WPF页面进行布局排版

2007-10-27 12:46 531 查看
2007年08月17日 13:46:00
对于以前用 Windows Form 来开发客户端程序的程序员,在使用 WPF 开发客户端的程序时,在窗体布局上将是他必须面对的一个坎。
布局产生困惑的一个典型场景如下:
我们在开发WPF窗体时候,我们会发现,当我们把菜单控件(Menu)、工具条(ToolBar、ToolBarPanel)、状态条(StatusBar)这些最常见的页面元素拖动到WPF窗体的时候。我们会发现 WPF 窗体中,这些页面元素可以放置在任何位置,而不是之前 Windows Form 那样:主菜单在最上面,状态条在最下面。
WPF中每一个元素如何布局变得更加灵活了,这样可以让美工更好的设计出更漂亮的页面,但是也会让一些缺乏艺术细胞的技术人员页面布局变得巨难看无比。比如我最近在写个简单的调查系统客户端维护工具,使用WPF程序来开发,这个页面布局的事情,就让我非常头大。
WPF 跟布局有关的控件很多,System.Windows.Controls.Panel 是这些所有布局有关的类的基类。需要注意的是,我们在页面布局上一般都是使用这个类的扩展类来处理布局,而不是使用这个类。这些扩展类包括:
System.Windows.Controls.Canvas (画布)
System.Windows.Controls.DockPanel (停靠布局)
System.Windows.Controls.Grid (表格)
System.Windows.Controls.StackPanel (堆栈布局)
System.Windows.Controls.VirtualizingPanel (虚堆栈布局)
System.Windows.Controls.WrapPanel (覆盖布局)

我自己在使用中觉得:对于我们从Window Form 习惯来的技术人员,使用 Grid (表格) 布局就可以满足我们绝大多数的布局需求,而且简单。下面我们就来介绍如何使用 Grid 布局控件来进行窗体布局设计。
Grid 布局控件很类似 HTML 标签中的 Table 标签。我们事先把一个区域划分成不同的表格,然后决定,某些控件放在那个表格中,那些控件是要跨多少个表格来放置。比如下面窗体效果,是由后面的XAML文件来实现这个效果的。



这个窗口布局上,我使用了Grid控件
我把这个窗口首先划分成三行三列的一个Grid。如上图我对这个窗体的拆分。
最上面的显示多少条目,以及下拉列表框,以及刷新按钮,被放在第一行,跨三列
未发布的调查表列表框被放在第二行,第一列,
支持来回拖动的GridSplitter被我放在了第二列,第二行
ListView 则被我放在了第二行,第三列
最下面的确定,取消按钮被我放在了第三行,跨了三个列
上述界面效果的XAML文件如下:

>Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="HongjunGuo.SurveySystem.Client.QuestionnaireList"
Title="调查列表" Height="300" Width="500"<
>Grid <
>Grid.ColumnDefinitions<
>ColumnDefinition Width="150"/<
>ColumnDefinition Width="5" /<
>ColumnDefinition Width="*"/<
>/Grid.ColumnDefinitions<
>Grid.RowDefinitions<
>RowDefinition Height="35"/<
>RowDefinition Height="*"/<
>RowDefinition Height="35"/<
>/Grid.RowDefinitions<
>DockPanel Height="30" Name="dockPanel2" Grid.ColumnSpan="3" Grid.Row="0"<
>Label<显示多少条目:>/Label<
>ComboBox Height="21" Name="comboBox1" Width="120" <
>ComboBoxItem IsSelected="True" <5>/ComboBoxItem<
>ComboBoxItem<10>/ComboBoxItem<
>ComboBoxItem<20>/ComboBoxItem<
>ComboBoxItem<50>/ComboBoxItem<
>/ComboBox<
>Button Height="23" Name="button1" Width="75"<刷新>/Button<
>/DockPanel<
>ListBox IsSynchronizedWithCurrentItem="True" Name="lb_Type" Width="Auto" Grid.Column="0" Grid.Row="1" <
>ListBoxItem Name="lbi_Draft" ToolTip="最近使用的,并且没有被发布的调查表" Content="本地未发布的调查表草稿" Height="50" IsSelected="True"/<
>ListBoxItem Name="lbi_Release" Content="本地最近发布的调查表" Height="50"/<
>ListBoxItem Name="lbi_Seatch" Content="服务器上的调查列表" Height="50"/<
>/ListBox<
>GridSplitter Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" Name="gridSplitter1" Width="10" /<
>ListView Name="lv_Data" IsSynchronizedWithCurrentItem="True" Grid.Column="3" Grid.Row="1"<
>ListView.View<
>GridView<
>GridViewColumn Header="编号"<
>/GridViewColumn<
>GridViewColumn Header="标题"<
>/GridViewColumn<
>GridViewColumn Header="创建时间"<
>/GridViewColumn<
>/GridView<
>/ListView.View<
>/ListView<
>DockPanel Height="30" Name="dockPanel4" Grid.ColumnSpan="3" Grid.Row="2"<
>Button Height="23" Name="btn_OK" Width="75" IsDefault="True" Click="btn_OK_Click"<确 定>/Button<
>Button Height="23" Name="btn_Cancel" Width="75" IsCancel="True"<取 消>/Button<
>/DockPanel<
>/Grid<
>/Window<
使用Grid布局控件的时候,一些知识点如下:
我们可以通过定义Grid的ColumnDifinitions和RowDifinitions来实现对于表格的定义,然后根据Grid.Column和Grid.Row的对象来制定位置的方式实现布局。
比如上面XAML文件中
>Grid <
>Grid.ColumnDefinitions<
>ColumnDefinition Width="150"/<
>ColumnDefinition Width="5" /<
>ColumnDefinition Width="*"/<
>/Grid.ColumnDefinitions<
>Grid.RowDefinitions<
>RowDefinition Height="35"/<
>RowDefinition Height="*"/<
>RowDefinition Height="35"/<
>/Grid.RowDefinitions<就定义了一个三行三列的表格。
ColumnDefinition 和 RowDefinition 分别只需要定义 Width 和 Height
如果我们希望列的宽度或者行的高度是根据内部元素来决定的,我们可以定义为 Auto, 如果我们希望某列或者某行的宽度或者告诉是整体的其他部分,则可以定义成 *,如果我们希望其中一项的长度是另外一项的5倍,则可以一个定义成*,一个定义成5* 。
我们看 ColumnDefinition 或者 RowDefinition 的 Width 或者 Height 属性的时候,我们可以看到这个属性不是 int或者 double 类型,而是 GridLength 类型。
下面一个简单的Grid定义来演示上面定义长度的几种写法
>Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300"<
>Grid <
>Grid.ColumnDefinitions<
>ColumnDefinition Width="30"/<
>ColumnDefinition Width="auto" /<
>ColumnDefinition Width="*" /<
>/Grid.ColumnDefinitions<
>Grid.RowDefinitions<
>RowDefinition Height="2*" /<
>RowDefinition Height="*" /<
>/Grid.RowDefinitions<
>Label Grid.Column="0" Grid.Row="0" Background="RosyBrown" <>/Label<
>Label Grid.Column="1" Grid.Row="0" Background="SkyBlue" <1234567890>/Label<
>Label Grid.Column="2" Grid.Row="0" Background="Red" <>/Label<
>Label Grid.Column="0" Grid.Row="1" Background="SpringGreen" <>/Label<
>Label Grid.Column="1" Grid.Row="1" Background="RoyalBlue" /Label<
>Label Grid.Column="2" Grid.Row="1" Background="Violet" <>/Label<
>/Grid<
>/Window<
这个XAML文件的效果图如下:



此外,我们还可以使用 Grid.ColumnSpan Grid.RowSpan 来实现一块布局跨多个表格项的情况。

小结:
我个人觉得,把一个窗体或者页面用表格拆分,然后我们在每个表格项中增加我们规划好的控件,这种布局方案在没有比较好的美术细胞下,比较容易做出一个至少不难看的页面布局。
基于以上的考虑,我觉得我们技术人员开发一些WPF窗体或者页面的时候,Grid控件应该是我们最常用到的。也应该是最应该掌握的控件。

参考资料:
WPF基本版面布局(精简版)
.Net Framework3.0 实践纪实(1)

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1748164
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: