WPF 的内部世界(控件与布局)
目录
前言
为什么要写WPF呢?
我一开始算是比较抵触WPF的,因为用的人少吗。感觉都是窗体应用能和Winform有什么区别。可是我错了,非常感谢我的讲师,给我推荐刘铁猛的《深入浅出WPF》,让我了解到了WPF的魅力——数据驱动UI 。
所以,这么优秀的框架,我想写下来,都知道WPF开发人员非常少,以至于大部分教程视频都是10年前的。我记录下来,不是为了什么,是真的喜欢WPF,那种“怪诞不经”的感觉。
一、UI布局
俗话说:“人靠衣装马靠鞍”
什么意思呢?意思是人穿上一身得体的衣服,就会显得分外精神;马备上一副讲究的鞍鞯,就会显得特别骏美。指衣服对人体的形象美有极大的影响。出自《薛仁贵征尔》
那么,我们把这句话引入到WPF中
- WPF作为专门的用户界面技术,布局的功能是它的核心功能之一。友好的用户界面和良好的用户体验离不开设计精良的布局。
- WPF设计师工作量最大的俩部分就是布局和动画,布局是静态的,动画是动态的,用户体验就是用 户在这动静之中与软件功能产生交互时的感受。
- 也就是说,布局就是WPF的衣服!
二、控件
"我老生涯鸥水相依,他旧风流鸿塞荒投。”
意思是野生动物和野生环境鸥水相依,不可分离
那么到WPF中呢? 一个页面的布局,显示。都是由一个个控件组成的。控件们离不开WPF这个赖以生存的环境,组成了一幅幅美丽生动的画面(布局)。
在开始学习这些布局元素前,我们要知道每个布局元素都有自己的特点,我们要灵活使用。切莫不要无所不用其极,要合理搭配。
(就像生态环境一样,要合理搭配,否则就会出现“生物入侵”这种“偷鸡不成蚀把米”的行为,加重了生态环境的负担。破坏)
1、 控件的分类
粗略而言,日常工作中我们打交道最多的控件无外乎6类,即:
- 1、布局控件:可以容纳多个控件或嵌套其他布局控件,用于UI上组织和排列控件,如:StackPanel,Grid,Dock,WrapPanel,,Canvas;
- 2、内容控件:只能容纳一个其他控件或布局控件作为它的内容,如:Button,Window;
- 3、带标题的内容控件:相当于一个内容控件,但可以加一个标题,如:Group Box,TabItem;
- 4、条目控件:可以显示一列数据,一般情况下这列数据的类型相同。如ListBox,ComboBox;
- 5、带标题的条目控件:相当于给一个条目控件加上一个标题显示区,如:TreeViewItem,MenuItem,往往用于显示层级数据;
- 6、特殊的内容控件:比如TextBox容纳的是字符串,TeztBlock可以容纳可自由控制格式的文本,Image容纳图片类型数据……这类的控件相对比较独立。
至于,为什么这么分类呢,其实我们只需要细细体会一下,就明白了。实在不行,你从工具栏拖出来,看着它的样子,在看着我的话。“什么?你还不懂”………………………………作者卒
好,我们不对这些控件做太多详细介绍,我们主要介绍布局控件,其他相信属性可以参考下面:
WPF 基本控件使用介绍:https://blog.csdn.net/niewq/article/details/50244227
三、布局控件
好了,终于来到我们的重点了。 WPF为我们提供了5中布局方式,他们的特点各不相同,可以相互嵌套,让我们来认识一下吧。
- 1、Grid :列表布局
- 2、StackPanel :堆栈面板布局
- 3、WrapPanel : 流布局面板(当元素水平对齐,内容超过宽度时,自动换行;当元素垂直对齐,内容超过高度时,自动换列)
- 4、DockPanel:停靠面板
- 5、Canvas:坐标面板
1、Grid列表布局
Grid一词译为“网格;格子,栅格”
没错,它就像一个网格一样把我们的页面分割成一块又一块。
我们在窗体放置了2个TextBlock和2个TextBox,想实现登录窗口的样式,可是不进人意,他们都重叠在了一起。
为什么都重叠在了一起呢?
因为,我们没有对Grid这个容器做相关调整,他现在是一个一行一列的“大格子”。在一个各自当然就重叠了,除非去设置Magin属性,当然我们想要实现的并不是这种效果。
所以,我们通过设置
- 列<Grid.ColumnDefinitions></Grid.ColumnDefinitions>
- 行<Grid.RowDefinitions></Grid.RowDefinitions>
“分割Grid”
我们可以通过添加ColumnDefinitions节点和RowDefinitions节点 ,来确定把我们的“Grid分割成几个格子”。
如图,分割成了四个格子:
通过看设计窗口,我们也会发现,Grid被线条分割成了四块:
唉?不对啊,为什么我们的控件还重叠的呢?是因为我们没有去设置他们处于哪个格子,接下载,我们设置一下。
确定位置,与合并单元格
当我们的容器处于Grid布局容器里时,会增加附加属性:
- 行所在位置: Grid.Row="0"
- 列所在位置: Grid.Column="0"
默认不设置,值为0 ,所以才会出现重叠的情况,来我们调整一下位置。
好了,一切恢复正常了,在增加一个按钮,登录怎么能没有按钮呢!
通过设置
- 行单元格合并: Grid.RowSpan="1"
- 列单元格合并: Grid.ColumnSpan="1"
默认值位1,合并几个就写几。
经过稍作修改,我们的界面变成了这样:
额……长得有点丑,我们添加些属性来调整一下,
设置宽高
我们通过对ColumnDefinition的Width来设置宽和RowDefinition的Height来设置高
Width和Height支持像素,比例,以及自适应
- 像素: 直接用数字表示即可
- 比例: 以*做单位
- 自适应: 设置值位 auto
好,我们来运用上面的知识,调整一下我们的视图:
总结
好,我们来总结一下上面的宽高:
- 首先我们对Grid的列经行了比例设置1:3(*,3*),当我们拉动窗体大小时,会发现它们的大小是等比例变化的。
- 其次,对Grid的行设定了俩个固定高度,我们可以发现无论窗体怎么变化他们的高度是不变的。
- 最后一行设定了自适应,我刻意把按钮的高度设为100,我们可以看到表格最后一行也为100,可以知道auto是根据内容来自适应的。
2、StackPanel堆栈面板
大家都对“堆栈”俩个词不陌生吧,堆栈面板就好像容器在“排队”一样,我们把Window下的Grid 换位StackPanel,来体验一下吧。
设置方向
我们在StackPanel里放置了很多按钮,发现他们就像排队一样,一个接一个,水平方向。如果你不喜欢这样,当然是可以改方向的啦!
通过设置Orientation
- 水平对齐: Orientation="Horizontal"
- 垂直对齐: Orientation="Vertical"(默认)
对于内部元素自身,也可以选择对其对齐方式
- HorizontalAlignment="left" Center,right
- VerticalAlignment="Top" Bottom,Center,Stretch
3、WrapPanel 流动布局
当元素水平对齐,内容超过宽度时,自动换行;当元素垂直对齐,内容超过高度时,自动换列)
它可能和上面的长得像,其实是不一样的。当StackPanel的内部子元素数量超出宽度(高度)会溢出窗体,而流动布局会自动换行。常用于动态数据生成。
这就不做详细介绍了,属性都和上面的一样。
4、DockPanel 停靠布局
做过winfrom开发的朋友,都知道一个Docl属性吧,那么我们的Dock布局也是这个道理,我们来实践一下。
在DockPanel的容器里的控件,会增加一个附加属性DockPanel.Dock
- DockPanel.Dock="Top"
- DockPanel.Dock="Bottom"
- DockPanel.Dock="Left"
- DockPanel.Dock="Right"
分别是上下左右停靠,要注意的是控件会随着设定的先后顺序,具有不同的宽高(或大小),默认最后一个停靠控件的大小占剩下界面的全部
仔细看左 和 右 ,你就会知道我说的注意项,新停靠的控件占剩余页面的所有区域。
5、Canvas 坐标布局
好吧,这个真的就相当于winform的布局了, 设置坐标,确定控件的位置。
在Canvas容器里的控件,会增加附加属性
- 距离窗口上方: Canvas.Top="20"
- 距离窗口左方:Canvas.Left="100"
- 距离窗口下方:Canvas.Bottom="20"
- 距离窗口右方:Canvas.Right="0"
四、综合小案例
如果都看完的话,我们来做一个小案例吧。
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="4*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.RowSpan="2" Grid.Column="0">
<Button Height="50">新建StackPanel</Button>
<Button Height="50">保存StackPanel</Button>
<Button Height="50">增加StackPanel</Button>
<Button Height="50">导入StackPanel</Button>
<Button Height="50">导出StackPanel</Button>
<Button Height="50">关闭StackPanel</Button>
</StackPanel>
<DockPanel Grid.Row="0" Grid.Column="1">
<TextBlock DockPanel.Dock="Top" HorizontalAlignment="Center">我是DockPanel</TextBlock>
<WrapPanel>
<Button Width="200">WrapPanel</Button>
<Button Width="200">WrapPanel</Button>
<Button Width="200">WrapPanel</Button>
<Button Width="200">放不下啦WrapPanel</Button>
<Button Width="200">WrapPanel</Button>
</WrapPanel>
</DockPanel>
<Canvas Grid.Row="1" Grid.Column="1">
<TextBlock Canvas.Top="100" Canvas.Left="100">Canvas账号:</TextBlock>
<TextBox Canvas.Top="100" Canvas.Left="200">Canvas请输入账号:</TextBox>
<TextBlock Canvas.Top="130" Canvas.Left="100">Canvas密码:</TextBlock>
<TextBox Canvas.Top="130" Canvas.Left="200">Canvas请输入密码:</TextBox>
</Canvas>
</Grid>
结束语 “不要用不公平掩饰你不努力的样子”
WPF 的内部世界(控件与布局)的更多相关文章
- UIButton内部子控件自定义布局-“UIEdgeInsets”
UIButton UIButton做frame动画时,不响应点击 在一个View内部加入几个按钮,然后改变这个view的frame来做动画,但是按钮不响应点击事件. 问题代码 __block CGRe ...
- 《深入浅出WPF》学习总结之控件与布局
一.控件到底是什么 控件的本质是“数据+算法”——用户输入原始数据,算法处理原始数据并得到结果数据.问题就在于程序如何将结果数据展示给用户.同样一组数据,你可以使用LED阵列显示出来,或者是以命令行模 ...
- WPF 基础 - 控件与布局
1. 前言 1. 数据驱动 UI WPF 是数据核心.主动的,UI 从属数据并表达数据.是被动的: 不再是 UI 驱动数据,而是数据驱动 UI: 2. 控件的定义 控件.数据内容.行为(控件响应用户操 ...
- WPF Step By Step 控件介绍
WPF Step By Step 控件介绍 回顾 上一篇,我们主要讨论了WPF的几个重点的基本知识的介绍,本篇,我们将会简单的介绍几个基本控件的简单用法,本文会举几个项目中的具体的例子,结合这些 例子 ...
- 在WPF中使用WinForm控件方法
1. 首先添加对如下两个dll文件的引用:WindowsFormsIntegration.dll,System.Windows.Forms.dll. 2. 在要使用WinForm控 ...
- Silverlight项目笔记1:UI控件与布局、MVVM、数据绑定、await/async、Linq查询、WCF RIA Services、序列化、委托与事件
最近从技术支持转到开发岗,做Silverlight部分的开发,用的Prism+MVVM,框架由同事搭好,目前做的主要是功能实现,用到了一些东西,侧重于如何使用,总结如下 1.UI控件与布局 常用的主要 ...
- [转]在WPF中使用WinForm控件方法
本文转自:http://blog.csdn.net/lianchangshuai/article/details/6415241 下面以在Wpf中添加ZedGraph(用于创建任意数据的二维线型.条型 ...
- 背水一战 Windows 10 (39) - 控件(布局类): VariableSizedWrapGrid, Border, Viewbox, SplitView
[源码下载] 背水一战 Windows 10 (39) - 控件(布局类): VariableSizedWrapGrid, Border, Viewbox, SplitView 作者:webabcd ...
- Wpf使用Winform控件后Wpf元素被Winform控件遮盖问题的解决
有人会说不建议Wpf中使用Winform控件,有人会说建议使用Winform控件在Wpf下的替代方案,然而在实际工作中由于项目的特殊需求,考虑到时间.成本等因素,往往难免会碰到在WPF中使用Winfr ...
随机推荐
- 5-2 SpringCloud | 微服务
服务器端项目演进 服务器初期状态 最早的服务器就是安装部署了一些静态页面 功能非常单一,只能做信息的呈现和输出 服务器动态页面 后来因为业务和技术的发展,页面连接了数据库,页面中大部分数据来自于数据库 ...
- ESXI启用本地登录和SSH服务连接功能,使用Xshell连接
1.选中Troubleshoot Options进行SSH服务配置 2.开启本地登录功能 3.开启远程连接功能 4.本地登录修改SSH服务允许基于密码登录 默认无法用密码登录ssh服务,只支持基于ke ...
- led闪烁(时序输入输出,自定义变量,时钟仿真,执行顺序)
1.设计定义 设计一个以200ms亮,200ms暗交替闪烁的led灯,并且有一个复位按钮可以停止工作. 2.设计输入 2.1端口 以固定周期交替闪烁说明由时钟控制,需要一个时钟控制端口clk,要求复位 ...
- 循环数组%操作下的一些解释(对于4.4UVA133的一些解释)
1.循环数组一般不推荐通过建立相同的数组不断叠加来实现,虽然理论上是可行的,但是会浪费极大的空间,特别是对于大数据的情况下,程序一般会马上挂掉 2.循环数组的结构表示中的一种常用形式就是通过取余操作来 ...
- Centos7中配置NIS:用户账号管理
NIS:网络信息服务 Linux系统中用户按地域分两类:本地用户,远程用户(NIS.LDAP.AD)模式:C/S模式 ypbind是定义NIS服务器的客户端进程,一旦确定了服务器位置,客户端绑定到了服 ...
- django自带的序列化组件
1.什么是序列化组件 在django中,自带一个序列化组件,它是用来将数据进行整理.转化成特定的为一个特定的格式(比如json数据格式),然后传输给前端,以便前端对数据进行处理操作. 2.为什么要用序 ...
- Git 06 分支
参考源 https://www.bilibili.com/video/BV1FE411P7B3?spm_id_from=333.999.0.0 版本 本文章基于 Git 2.35.1.2 概述 分支用 ...
- java学习第七天lo流.day17
lo输入
- Excel 数学函数(三):RAND 和 RANDBETWEEN
Excel 主要有 RAND 和 RANDBETWEEN 这两个函数生成随机数.RAND 默认生成 0~1 的随机数:RANDBETWEEN 有两个参数:bottom 和 top,bottom 代表函 ...
- Java精进-20分钟学会mybatis使用
文字分享 希望现在的你无论有明确具体的目标还是没有,都能重视自己的需求和目标,并且常常回顾,或许可以找一个你习惯的方式写出来,挂在哪里,电脑或日记本都好.当你疲惫或迷茫的时候拿出来看一下,这在情怀领域 ...