说到WPF的界面布局,相信很多朋友都写过Html代码。在WPF中,大多数程序都使用类似Web的(flow)流布局。在使用流布局模型时,各种控件可以按特定的要求来排列,在窗口内容发生变化时,比如窗口大小发生变化,界面可以调整自身以及控件的布局。

WPF的布局原则和HTML比较类似,但也有些不同,下面让我们具体来看看:

WPF布局原则

  1. 不应显示设定元素(如控件)的尺寸: 元素应该可以改变尺寸以适应他们的内容,例如当添加更多文本时按钮应当能够扩展。很多时候我们在HTML中设置MinWidth 或者 MaxWidth之类属性去限制控件的尺寸范围,在WPF也有同样的应用。
  2. 不应使用屏幕坐标指定元素的位置:元素应该由他们的容器根据他们的尺寸、顺序以及其他特定于具体布局容器的信息进行排列。上面所说的意思其实也和HTML中的元素位置设定很类似,虽然很多时候我们在HTML中也使用坐标进行定位,但实际上这样的使用情况非常少。
  3. 布局容器的子元素“共享”可用的空间:如果空间允许,布局容器会根据每个元素的内容尽可能为元素设置更合理的尺寸。它们还会向一个或多个子元素分配多余的空间。这点和HTML中设置各个子元素的宽度和高度很类似,我们可以使用具体的像素(PX)来设置元素尺寸,也可以使用百分比(%)来设置元素所占用的空间,另外子元素为了能填充父元素的空间,可能还对有自动的宽度和高度的调整。
  4. 可嵌套的布局容器:在WPF中典型的用户界面使用Grid面板作为开始,Grid面板可以包含其他布局容器。这点也很像Html中的嵌套,我们可以在<Div>中包含再包含<Span>,也可以在<span>中再包含<label>,类似上面的例子的嵌套情况在WPF中也是很常见的。

 

WPF布局过程

WPF布局包括2个阶段:测量(measure)和排列(arrange)。在测量阶段,布局容器会遍历所有子元素,并询问子元素他们所期望的尺寸,在适合的位置放置子元素。

WPF布局容器

在HTML中我们有多种布局的容器,例如<div>、<table>等等,那么在WPF也存在类似的控件,所有WPF的布局容器都派生自System.Window.Controls.Panel, 下面让我们来看下Panel类的层次结构:

WPF提供了大量可用于安排布局的继承自Panel的类,这里我们列举几个最基本的类。与所有WPF空间和大多数可视化元素一样,这些类位于System.Windows.Controls的命名空间中。

名称

说明

StackPanel

在水平或垂直的堆栈中放置元素

WrapPanel

在一系列可换行的行中放置元素

DockPanel

根据容器的整个边界调整元素

Grid

根据不可见的表格在行和列中排列元素,最常用的容器之一

UniformGrid

在不可见,但是强制所有单元格具有相同尺寸的表格中放置元素

Cavas

使用固定坐标绝对定位元素

StackPanel的使用

上面讲到了一些关于布局容器的概念和类的说明,现在让我们依次来看下这些常用的布局容器。

首先我们来看下StackPanel,StackPanel面板是WPF中最简单的面板之一,该面板简单地在单行或列中以堆栈形式放置其子元素,默认情况下面板按自上而下的顺序排列元素,并且使每个元素的高度适合它的内容,下面让我们来看一个测试代码:

<Window x:Class="StackPanelTest.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">
<StackPanel>
<Label>A button click</Label>
<Button>Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
<Button>Button 4</Button>
</StackPanel>
</Window>

其运行的结果如下图,所有Button都自上而下排列,按钮的大小刚好足够适应他们内部的文本,所有的元素都被拉伸到StackPanel面板的整个宽度。

和HTML的某些控件类似,比如RadioButtonList之类的,我们也可以控制元素的的排列方向,在StackPanel中,我们使用Orientation属性来控制子元素的排列方向:

<StackPanel Orientation="Horizontal">

布局属性

StackPanle的布局属性与HTML的布局容器很类似的,都可以设置对齐方式,外边距,最大最小宽度、高度等。

1. 对齐方式

首先我们来看下对其方式,在StackPanel中如果是垂直方向的排列,那么VerticalAligment属性不起作用,因为所有元素的高度都自动地调整为刚好满足各自需要,但是HorizentalAligment属性非常重要,它决定了各个元素在行的什么位置。HorizentalAligment有4个值可以选择:Left, Center, Right 和 Stretch, 相信熟悉Html代码的朋友来说,前面3个值很容易理解,最后一个值Stretch会将子元素拉伸至整个StackPanel面板的宽度,并且会被设置为默认值,让我们来看下具体的代码:

<StackPanel Orientation="Vertical">
<Label HorizontalAlignment="Center">A button click</Label>
<Button HorizontalAlignment="Left">Button 1</Button>
<Button HorizontalAlignment="Right">Button 2</Button>
<Button>Button 3</Button>
<Button>Button 4</Button>
</StackPanel>

当设置了对其方式后,按钮的长度和位置都发生了变化,如下图:

我们看到Button1和Button2设置了对其方式后,他们的位置和按钮的宽度都发生了变化,这些实际上和HTML中元素的对其方式都很类似的,需要注意的就是Stretch对齐方式对拉伸子元素的宽度为整个StackPanel的宽度。

 2. 边距

在我们平时的布局中,一般不会让相邻元素靠得太近,所以在Html中,我们一般会加入Margin这样的CSS样式来控制元素的边距。在WPF中,也有类似的情况,我们可以设置Margin属性来调整元素的边距,代码实例如下:

<Button Margin="5,10,5,4">Button 4</Button>

上面的4个值以逗号分隔,这也和CSS中的设置一样,分别为上,右,下,左。下图为设置了Margin的子元素,相邻的2个子元素之间的距离,为他们各自Margin 之和,代码如下:

<StackPanel Orientation="Vertical">
<Label HorizontalAlignment="Center">A button click</Label>
<Button HorizontalAlignment="Left">Button 1</Button>
<Button HorizontalAlignment="Right">Button 2</Button>
<Button Margin="30">Button 3</Button>
<Button Margin="40">Button 4</Button>
</StackPanel>

运行结果如下图:

我们可以在XAML中设置Margin,也可以在C#代码中声明,在代码中我们使用Thickness结构来设置边距:

btnShow.Margin = new Thickness(,,,);

3.最大尺寸、最小尺寸

每个元素都提供Width和Height属性,用于显示的指定元素的大小,但有时候子元素的大小超过了父容器的大小时,我们就应当将子元素限制在正确的范围内,这个时候我们可以用MaxWidth和MaxWidth来进行设置,让我们来看下示例代码:

<Button MaxWidth="200" MaxHeight="100" Margin="40">Button 4</Button>

运行结果如下图:

从上图我们可以看到,Button4的默认的对齐方式为Stretch,Button4的宽度本来被拉伸至整个StackPanel的宽度,由于我们设置了MaxWidth,最后Button4实际的宽度被设置为200,这样子就达到了我们要调整合适宽度的目的。

上面就为我们今天说到的第一个布局控件(StackPanel),后续还会为大家梳理其他的布局控件。

本人最近开始学习WPF以及DevExpress,藉此提升自己C/S架构编程的能力。在学习过程会有一些心得体会,于是便会写一些博客来记录这些想法,有兴趣的朋友可以和我一起交流学习。那么就让我们从这里开始WPF与DevExpress的旅程吧!

QQ群: 32745894,欢迎大家加入讨论!

WPF之旅(三)- 布局之StackPanel的更多相关文章

  1. WPF教程二:布局之StackPanel面板

    应用程序界面设计中,合理的元素布局至关重要,它可以方便用户使用,并将信息清晰合理地展现给用户.WPF提供了一套功能强大的工具-面板(Panel),来控制用户界面的布局.你可以使用这些面板控件来排布元素 ...

  2. WPF中的常用布局

    一 写在开头1.1 写在开头评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好. 1.2 本文内容本文主要内容为WPF中的常用布局,大部分内容转载至https://blog.csdn.net ...

  3. [No000012A]WPF(2/7):布局,容器和布局转换[译]

    概要 在上一篇文章中,我讨论了一些WPF应用的基础知识,它们是使用WPF的基本架构和内部结构.在本文中,我将讨论编写你的第一个WPF程序的基本的东西和怎么在你的窗口中布局控件.这是每一个想使用WPF的 ...

  4. WPF中的常用布局 栈的实现 一个关于素数的神奇性质 C# defualt关键字默认值用法 接口通俗理解 C# Json序列化和反序列化 ASP.NET CORE系列【五】webapi整理以及RESTful风格化

    WPF中的常用布局   一 写在开头1.1 写在开头微软是一家伟大的公司.评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好,应该抛弃对微软和微软的技术的偏见. 1.2 本文内容本文主要内容 ...

  5. WPF笔记(1.4 布局)——Hello,WPF!

    原文:WPF笔记(1.4 布局)--Hello,WPF! 这一节只是第2章的引子.布局要使用Panel控件,有四种Panel,如下:DockPanel,就是设置停靠位置布局模型.StackPanel, ...

  6. WPF项目学习.三

    工具代码记录 版权声明:本文为博主初学经验,未经博主允许不得转载. 一.前言 记录在学习与制作WPF过程中遇到的解决方案. 分页控件的制作,邮件发送,日志代码,excel导入导出等代码的实现过程: 二 ...

  7. WPF自定义控件(三)の扩展控件

    扩展控件,顾名思义就是对已有的控件进行扩展,一般继承于已有的原生控件,不排除继承于自定义的控件,不过这样做意义不大,因为既然都自定义了,为什么不一步到位呢,有些不同的需求也可以通过此来完成,不过类似于 ...

  8. Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)

    jquery提供的serialize方法能够实现. $("#searchForm").serialize();但是,观察输出的信息,发现serialize()方法做的是将表单中的数 ...

  9. WPF系列教程——(三)使用Win10 Edge浏览器内核 - 简书

    原文:WPF系列教程--(三)使用Win10 Edge浏览器内核 - 简书 在需要显示一些 H5网站的时候自带的WebBrowser总是显示不了,WebBrowser使用的是IE内核,许多H5新特性都 ...

  10. 用Visual C++创建WPF项目的三种主要方法

    用Visual C++创建WPF项目的三种主要方法 The problem with using XAML from C++ Because C++ doesn't support partial c ...

随机推荐

  1. leetcode 题解 Add Two Numbers(两个单链表求和)

    题目: You are given two linked lists representing two non-negative numbers. The digits are stored in r ...

  2. a 中调用js的几种方法

    我们常用的在a标签中有点击事件:1. a href="javascript:js_method();" 这是我们平台上常用的方法,但是这种方法在传递this等参数的时候很容易出问题 ...

  3. pl sql 变量的声明和赋值

    链接地址:http://www.cnblogs.com/zhengcheng/p/4168670.html 一.什么是PL-SQL PL-SQL是结合了Oracle过程语言和结构化查询语言(SQL)的 ...

  4. 2013 ACM/ICPC Asia Regional Online —— Warmup2

    HDU 4716 A Computer Graphics Problem 水题.略 HDU 4717 The Moving Points 题目:给出n个点的起始位置以及速度矢量,问任意一个时刻使得最远 ...

  5. 统计机器学习(statistical machine learning)

    组要组成部分:监督学习(supervised learning),非监督学习(unsupervised learning),半监督学习(semi-supervised learning),强化学习(r ...

  6. Person

    using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace PersonD ...

  7. 【奇怪现象】用联通访问某些ASP.NET网站会产生__EVENTVALIDATION字段,用电信却只有:__VIEWSTATE。【正常】?原因?

    [奇怪现象]用联通访问某些ASP.NET网站会产生__EVENTVALIDATION字段,用电信却只有:__VIEWSTATE.[正常]?原因? 对于__VIEWSTATE和__EVENTVALIDA ...

  8. Part 11 Search filter in AngularJS

    As we type in the search textbox, all the columns in the table must be searched and only the matchin ...

  9. HTML之正则表达式

    匹配国内电话号码:d{3}-d{8}|d{4}-d{7} 评注:匹配形式如 0511-4405222 或 021-87888822 匹配腾讯QQ号:[1-9][0-9]{4,} 评注:腾讯QQ号从10 ...

  10. Sql Server 数据库之间如何进行跨网远程连接访问

    场景说明 现在有一台A电脑和一台B电脑,两台电脑都安装了Sql Server数据库,两台电脑不在一个局域网(我们考虑的是不同网络的两台数据库连接),比如A电脑在公司,B电脑在家里,现在我要在家里用B电 ...