WPF之旅(三)- 布局之StackPanel

说到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(5,3,2,1);

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,欢迎大家加入讨论!

时间: 2024-10-25 20:00:26

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

WPF实现界面动态布局

以前总觉得动态布局是个很麻烦的问题,是个很需要功力的问题.但是貌似在.NET中,在WPF中却不是那么的麻烦.下面介绍我现在实现的一个动态布局的实例. 因为有需求,所以困难得克服!而我们的需求表名,不同的用户需要的界面元素是不一样的,我们总不能每次都去修改代码吧!所以,需要完成动态布局. 这里主要完成这样一个功能: 1.动态画线 2.动态new控件 3.线和控件都是可拖拽并随意放置位置的 4.线和控件是可删除的 5.控件是可绑定属性和事件的 要完成这样的功能,我们首先得定义三个鼠标事件,即:左键d

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

原文:WPF笔记(1.4 布局)--Hello,WPF! 这一节只是第2章的引子.布局要使用Panel控件,有四种Panel,如下:DockPanel,就是设置停靠位置布局模型.StackPanel,提供一个从左至右或从上至下放置内容的堆栈模型.Grid,提供一个允许进行 行/网格定位的模型.可使用表格.Canvas,可精确定位. 其中,Grid是最常用的,vs2005自动生成的Page和window都默认带有这个标签: Example 1-25. A sample usage of the G

WPF项目学习.三

工具代码记录 版权声明:本文为博主初学经验,未经博主允许不得转载. 一.前言 记录在学习与制作WPF过程中遇到的解决方案. 分页控件的制作,邮件发送,日志代码,excel导入导出等代码的实现过程: 二.配置 系统环境:win10 开发工具:Visual Studio 2017 开发语言:C#.WPF (MVVM框架) 三.功能 1. 分页控件的制作 1.1 前端xaml代码 <UserControl x:Class="SCB.RPS.Client.Controls.UcPager"

Android 性能优化 三 布局优化ViewStub标签的使用

小黑与小白的故事,通过虚拟这两个人物进行一问一答的形式来共同学习ViewStub的使用 小白:Hi,小黑,ViewStub是什么?听说可以用来进行布局优化. 小黑:ViewStub 是一个隐藏的,不占用内存空间的视图对象,它可以在运行时延迟加载布局资源文件.(更多详细的API等信息可以查看官方文档ViewStub),计算机行业一向是实践里面出真知,下面用一个例子演示下效果. 小黑:说说概念只是为了概括性的了解下,还是用个实例来演示下.先来创建一个Activity中使用的布局文件,文件名是:act

Ajax之旅(三)-- 异步更新

上篇博文中,已经为大家在理论上讲述了什么是XMLHttpRequest对象,它是Ajax实现异步更新的核心对象.下面,我们就通过一个实例,来了解XMLHTTPRequest对象的使用或者说异步更新的实现. 实例:判断用户代码是否重复        方案一:同步更新.原理如下图所示: 从上图中可以看到,当我们在浏览器用户代码输入框中输入"用户代码"后,只能等待服务器的响应,当服务器将结果反馈给浏览器后,我们才可以进行下一个操作,也就是继续输入"用户名称". 这就是同步

WPF异常捕获三种处理 UI线程, 全局异常,Task异常

原文:WPF异常捕获三种处理 UI线程, 全局异常,Task异常 protected override void OnStartup(StartupEventArgs e){base.OnStartup(e);RegisterEvents();} private void RegisterEvents(){//TaskScheduler.UnobservedTaskException += (sender, args) =>//{// MessageBox.Show(args.Exception

[WPF] VisualBrush 中的布局

原文:[WPF] VisualBrush 中的布局 今天插一篇随笔.说一说上周五遇到的一个布局问题,问题大概是这样的:需要在一个快区域上添加一张透明的背景图片,由于区域较大.并且宽高都不是固定大小,图片较小 所以图片需要居中显示.除此之外还需要在图片的透明部分添加一个非透明的纯色. 比如:最终的效果图.如下图所示: 当然如果只是为了实现这种效果.实现方案有多种,至少有三大类: 1.嵌套两个控件.分别应用纯色 和 居中图像. 2.使用 VisualBrush 将组合效果应用在同一个控件的Backg

WPF学习之旅---页面布局

WPF布局执行工作 测量:容器遍历所有子元素,并询问子元素所期望的尺寸 排列:容器在合适的位置放置子元素,并设置最终尺寸 height,width:元素期望尺寸 Actualheight,Actualwidth:实际尺寸 布局继承机制 DispatherObject:WPF应用程序使用单线程亲和模式,每个用户界面只被一个单线程使用. DependebcyObject:依赖属性,在winform控件中,控件通常默认保存初始化值,这样就浪费资源,依赖属性就是解决这一问题,默认的属性只保存一份 Vis

WPF入门——XAML和布局容器

WPF是微软推出的基于Windows Vista的用户界面框架:它提供了统一的编程模型.语言和框架,真正做到了分离界面设计人员与开发人员的工作.WPF和.NET中winForm是类似的. XAML 1.XAML是对WPF程序的所用用户界面进行详细的定制. 2.它提供了一种便于扩展和定位的语法来定义和程序逻辑分离的用户界面,而这种实现方式和ASP.NET中的"代码后置"模型非常类似. 3.但是XAML并不是一种用于程序设计的语言,它的功能也不是为了执行应用程序逻辑. 4.说的通俗一点,W