WPF布局总结
一、基本原则... 1
二、布局分析... 2
1.观察界面整体框架... 2
2.依次设置各个模块的内容... 2
3.整体分析图... 3
4.分析小结... 3
三、界面特效... 3
1.根据不同的值显示不同图片... 3
2.按钮可用不可用的切换... 4
3.页面呈现集合排版... 5
4. WPF按钮点击变色... 5
四、小技巧... 6
1.消除ListBox项被选中的自带样式... 6
2.ComboBox控件... 6
3.元素简单排列样式... 6
4.排列元素注意... 7
五、常用面板... 7
一、基本原则
布局过程包括两个阶段:一个测量阶段和一个排列阶段。在测量阶段,包容器遍历所有的子元素,并询问子元素他们所期望的尺寸。在排列阶段,包容器在合适的位置放置子元素。
WPF 布局原则:
1.不应使用屏幕坐标指定元素的位置。元素应当由它们的包容器,根据它们的尺寸、顺序以及其他特定于具体布局包容器的信息进行安排。如果需要在元素之间添加空白空间,可以使用Margin属性。
2..布局包容器和它们的子元素“共享”可以使用的空间。如果空间允许,布局包容器会根据元素的内容尽可能为它所包含的元素设置更合适的尺寸。它们还会向一个或多个子元素分配多余的空间。
3.布局包容器可以被嵌套。一个典型的用户界面使用一个Grid面板作为开始,Grid面板是WPF中功能最强大的布局控件,并且Grid面板可以包含其他布局包容器,包含的这些包容器以更小的分组安排元素。
二、布局分析
1.观察界面整体框架
整个界面是由外而内一层层模块组成。首先使用Grid面板分割出大的面板框架。举例说明:我们大致观察下图后可以发现这个页面可以首先分为三块,使用Grid作为最外面的包容器分出这几块,划分如下图:
我们使用Grid划分好这几块以后,要注意这些块的宽度和高度的设置。
l 如果页面的大小(1440*900)固定不变的,并且一直都是全屏状态,那么我们可以在设置行高与列宽的时候使用固定值,例如行高可以依次设置为:205、620、75。需要注意的是这些宽度高度总和等于窗口的宽度或高度。
l 如果页面是可以改变大小的窗口,我建议使用百分比设置宽度和高度,例如:2*、6*、2*,总宽度或高度为10*。这样设置后,改变窗口的时候,窗口里面的元素布局不会发生畸形,可以适应窗口的大小。
2.依次设置各个模块的内容
最好是给每个模块都加上一个面板。不要在多控件的模块里面每次都设置元素的Grid.row 与Grid.column,不加外层面板时,一旦界面发生变动,修改这些元素会比较浪费时间,很难维护。同时,坚决不要直接使用鼠标拖动控件到设计视图上,使用Margin值直接将控件绝对定位,这样很难达到美观的效果,并且调整界面控件的整齐度时比较浪费时间,也加大了维护的困难。
以上图为例:我们将第一部分进行划分
注意我划分的位置是特别贴近最左边的控件与最右部分的控件的,这样设置列宽也是为了更好的定位控件的停靠。我们依次设置如下:
① 最左边的返回按钮,我们可以直接设置 HorizontalAlignment="Right" VerticalAlignment="Center" 这两个值达到按钮停靠效果,我建议能够实用这两个值解决的样式问题,尽量不使用Margin定位。
② 同样的道理我们使用HorizontalAlignment使得最右边的大容器向左停靠,容器中的控件是分为两行的,可能我们会觉的使用Grid太过于麻烦的分行分列,此时我们可以使用三个StackPanel进行解决。我们看到的块控件整体偏下,此时设置VerticalAlignment="Bottom",设置底边距调整容器的位置。 (我建议如果需要设置一个容器的Margin值时,我们先观察这个容器比较靠近的位置,如果比较靠右,我们就设置HorizontalAlignment=“right”再设置margin值右边距,这样比设置左边距会使需要设置的距离值更加准确,小的距离总是要比大的距离更加容易把握与调整。设置上下边距时也是相同的道理。)
③ 中间位置的元素相信也很简单,不需要我再描述设置了。
3.整体分析图
步骤:①先使用Grid划分红线为边的三行。
②划分头部,以绿线划分为三列,并填充控件。
③划分中部,以黄线划分为三列,中间一列可以设置stackpanel包含两个容器,一个置顶,一个置底部。
④划分底部,以白线划分成两个部分,一个置左,一个置右,可以使用Grid、也可以使用StackPanel。
4.分析小结
布局时我们不能怕麻烦怕繁琐而不去给每个多元素的区域包装一个面板,省略包装面板的结果往往会给界面发生变化修改时带来更大的麻烦。一定程度上也降低了界面的美观度。
如果不能保证自己排出的界面如设计图一样美观,我建议,暂时将设计图设置为排版页面的背景图片,划分模块后,在容器中,一点一点的设置控件的定位以求达到完美。
三、界面特效
1.根据不同的值显示不同图片,此时我们就会想到使用触发器。
例如:根据在线与离线的状态呈现绿色与灰色图片
<Style TargetType="Grid">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/Messenger;component/
Styles/Images/ContactList/status_NA.png" />
</Setter.Value>
</Setter>
<Style.Triggers>
<!--0 离线-->
<DataTrigger Binding="{Binding User.OnlineState}" Value="0">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/Messenger;component/
Styles/Images/ContactList/status_offline.png" />
</Setter.Value>
</Setter>
</DataTrigger>
<!--1 在线-->
<DataTrigger Binding="{Binding User.OnlineState}" Value="1">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/Messenger;component
/Styles/Images/ContactList/status_online.png" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
2.按钮可用不可用的切换,可以使用数据触发器
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=lbFriends,Path=SelectedItems.Count}" Value="0">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Image Width="110" Height="40" Source="/Messenger;component/Styles/Images
/DeleteContacts/btn_Ok.png"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="IsEnabled" Value="False"></Setter>
</DataTrigger>
</Style.Triggers>
3.页面呈现集合排版,经常使用的ListBox或者ItemsControl。例如显示群的集合
集合中包含集合的时候可以在ListBox的DataTemplate中设置面板包含多个组。面板中使用ListBox呈现每组的组员集合。
4. WPF按钮点击变色
<Style x:Key="SwitchImageButtonStyle" TargetType="{x:Type Button}" BasedOn="{x:Null}">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"/>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="true">
<!--IsPressed-->
<Setter TargetName="Border" Property="Background" Value="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
四、小技巧
1. 消除ListBox项被选中的自带样式
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
2. ComboBox控件
如果使用它包装上千个项,当单击箭头打开组合框的下拉部分时,就会出现不可接受的延迟。这是因为尽管组合框值显示所有项的一个子集,但是它仍然迭代整个列表并为每个项创建一个元素。解决方式是对在于Combox控件中宿主的项像是插入一个VirtualizingStackPanel包容器。
<ComboBox>
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel></VirtualizingStackPanel>
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
3.元素简单排列样式
①横排样式:
这种情况下可以选择Grid,也可以使用StackPanel,将StackPanel的属性Orientaion=”Horizontal”就可以达效果,默认情况下它是垂直排列元素的。如果元素间有距离的话,就设置margin值。
②竖排样式:
同理,可以进行Grid设置第二个元素的margin,也可以直接使用StackPanel
③覆盖排列:
直接使用Grid即可,不需要设置任何的marign值,将要覆盖在上面的控件最后排出来即可。
4.排列元素注意
成排的文字或者文本框,要使这些文本框保持统一的对齐方式,文字大小与颜色也要保持一致,在调试文本颜色的时候要配合页面的背景颜色以保持协调。如果空间足够大,建议文本框的宽度设置的稍微长些,例如300。如果文本框高度较大,请设置文本框的内容上下居中,以及文本框字体大小适当。
注意控件与页面边缘的距离,不要使得控件太过于靠近边缘,要保持适当的边距。如果需要设置背景图片,请与程序主界面保持相同的风格。同时需要注意排出的界面如果是Window,请根据主界面风格适当的弹出window的位置,根据top、left设置。
五、常用面板
l StackPanel 在一个水平或垂直的堆栈中放置元素。通常用于一个更大更复杂窗口中的一些小区域。其VerticalAlignment属性不起作用,因为所有元素的高度都自动地调整为刚好满足其需要。
l WarpPanel 在一系列可换行的行中放置元素。水平方向上,WarpPanel面板以从左向右的方式放置元素,然后再在随后的行中放置元素。在垂直方向上,WarpPanel面板在从上到下列中放置元素,并使用附加的列放置剩余的元素。WarpPanel面板是唯一一个不能够通过灵活使用Grid面板代替的布局包容器。
l DockPanel 根据包容器的整个边界调整元素。
l Canvas 使用固定的坐标绝对定位元素。
l Grid 根据一个不可见的网格在行和列中安排元素。Grid 支持三种改变尺寸的方式:1.绝对改变尺寸方式。2.自动改变尺寸方式。每行和每列的尺寸刚好满足需要,“Auto”表示。3.按比例改变尺寸方式,使用“*”表示。