WPF高级教程(三)XAML
语言简介
- XAML(Extensible Application Markup Language) 是用来写界面的
- XAML是大小写敏感的
- WPF是前后端分离的,前端用XAML实现,后端用C#写(注意能用XAML写的都能用C#实现,但是用XAML更加直观,我们在本篇教程里,一般只说明使用XAML的实现,如果大家需要在后台更改界面,可以自行搜索XAML对应的C#实现)
命名空间
格式
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- http:// 并不是一个网址,而是十几个命名空间的集合,这样做,既保证了这个Uri不会于用户自定义的命名空间重复(因为schemas.microsoft.com是微软所有的)也降低了文档的复杂程度,不用写十几个命名空间了。
- xmlns:x 表示这个命名空间的别名是x,在使用的过程中可以通过x:Name使用这个命名空间下的对象
- presentation 是WPF核心命名空间,没有前缀,默认(像Button这种)都在这个命名空间之内
- xaml 是XAML的命名空间
不同项目中的命名空间的引用
xmlns:Prefix="clr-namespace:Namespace;assembly=AssemblyName"
注意AssemblyName是程序集名称,只要在该项目中引用过即可使用。如果就在本程序集中,则可以忽略这个选项。
// 把当前项目程序集设置为local
xmlns:local="clr-namespace:MyNamespace"
类名 部分类
x:Class="Novc.ViPlex.Express.View.AboutView"
这个声明使得XAML生成了一个部分类,与后台的部分类一起构成了完整的窗体类定义
XAML加载
InitializeComponent方法
- 这个方法的作用是加载XAML并且构建用户界面
- 当自定义构造函数的时候必须写上这个方法
事件和属性
XAML加载的顺序是先设置Name属性,再给元素挂载事件,最后加载属性。所以,如果监听了某个属性的变化的事件,在第一次设置该属性的时候(加载属性的时候),事件都会触发一次。
属性的类型转换器(TypeConverter)
在XAML中,属性的设置全部是字符串类型的,但是属性的类型却是多种多样的,比如Image的Source是一个BitmapImage类型,VerticalAlignment是枚举类型。为了解决这个问题,.NET引入了类型转换器的概念
类型转换器存在于
- 需要设置的属性中,比如 Background 属性
- 属性设置的值中,比如Background需要使用一个Brush对象,XAML也会检测Brush中是否有类型转换器
属性的设置
直接设置属性(使用类型转换器)
HorizontalAlignment="Left"
设置复杂属性
属性元素语法,语法规则为Parent.Property,用于设置一个复杂的,对象类型的属性值。<Grid HorizontalAlignment="Left" Height="100" Margin="196.617,195.39,0,0" VerticalAlignment="Top" Width="118.795"><Grid.Background><LinearGradientBrush><GradientStop Offset="0.00" Color="Red"></GradientStop><GradientStop Offset="0.50" Color="Indigo"></GradientStop><GradientStop Offset="1.00" Color="Violet"></GradientStop></LinearGradientBrush></Grid.Background> </Grid>
使用标记扩展设置属性(不太常用,知道即可)
当我们要给一个属性设置为一个已经存在的属性的时候使用,例如,A类中有一个静态的Brush,B.xaml中需要使用A中的Brush,需要注意的是,A中的Brush必须是静态的,即通过类名就可以访问。
<Button Foreground="{x:Static SystemColors.ActiveCaptionBrush}"/>
注意上面的语法,Static是StaticExtension的简写,即静态扩展,在后台中这样写
cmdAnswer.Foreground = SystemColors.ActiveCaptionBrush;
作为嵌套属性这样写,注意需要使用Member:
<Button.Foreground><x:Static Member="SystemColors.ActiveCaptionBrush"/> </Button.Foreground>
设置附加属性
简单说,附加属性就是一些属性只有在某种特性情况下才能被设置,比如控件在Grid中的时候才能设置Grid.Row。
这里我们多分析两句,想必设置Grid.Row人人都会,但是为什么它叫附加属性呢?因为TextBox中本来没有这个属性,Background,TextAlignment这种都属于控件的固有属性,而Grid.Row这种是添加进去的。这个属性不在FrameworkElement这样的基类中,而在DependencyObject中有一个字典,这个字典中保存所有扩展属性的Key和Value,因为保存它的是一个字典,所以它可以扩展,那么设置Grid.Row就等价于下面的代码
txtQuestion.SetValue(Grid.RowProperty, 1)
为什么不写在基类中,要写成这样呢?很简单,因为不是所有的组件都需要这个属性,只有在Grid中的组件有可能需要设置这个属性,所以,做成可扩展的就不扰乱基类,也可以方便扩展。
元素树
我们知道元素是以嵌套的方式进行构建的,构建的方式是:
- 如果父元素实现了IList接口,就调用IList.Add
- 如果父元素实现了IDictionary接口,就调用IDictionary.Add
- 如果父元素使用了ContentProperty修饰,子元素设置对应的属性
我们最需要关注的就是ContentProperty属性,因为ContentControl,ItemsControl,Panel基类都使用ContentProperty特性,这就是说几乎所有的控件都使用ContentProperty,而IList接口的多是属性等,在设置属性的时候可以设置一个集合。
对于Grid中加入各种元素的情况,并不是因为Grid是IList的集合,Grid支持的是ContentProperty,而能加入很多元素是因为Grid继承自Panel,Grid使用Panel渲染ContentProperty属性,实现可以添加多个元素。Panel有一个Children属性是一个集合,添加元素就是往Children中加入元素,看以下代码
txtQuestion = new TextBox();
grid.Children.Add(txtQuestion);
那什么父元素是IList的呢?之前就说过了,比如之前的GradientStopCollection,里面可以添加很多个GradientStop
对于Grid我们说过了,那对于简单元素,就更简单了。TextBox的ContentProperty渲染的是Text属性,Button的ContentProperty渲染的是Content属性,这里我们要讨论以下Text属性和Content属性的区别了。
Text 属性和 Content属性
当我们指定控件中的文字的时候,我们发现有一些控件需要指定Text属性,有一些控件却是要指定Content属性,那么这两个属性有什么区别呢?其实区别很简单,Text属性只能接受string类型的值,那么控件中就只能添加文字,Content属性就比较丰富多彩,可以放各种各样的东西。看下面的例子说明一下。
<Button><Button.Content><Image Source="/Image/1.jpg"></Image></Button.Content>
</Button>
实体字符集
< > " & 这些作为XAML的关键字,不能在XAML中直接显示,当我们要显示这些字符的时候需要用到实体字符标记。
<Button><Click>
</Button>
// 显示出来的是<Click>
注意在代码中设置Content不用遵循这个规则,而是需要遵循C#的转义规则。
空白处理
默认
折叠所有空白(打多少空格都只显示一个),如果想要显示所有的空格,有下面三种办法
- 在代码中设置的空格多少个都会被保留
- 使用 xml:space=“preserve” 属性
- 在属性中设置的多少个空格都会被保留
// 空格会保留
<TextBlock Text="[1 3 5 7]" />// 空格会保留
<TextBox xml:space="preserve">1 2 3 4
</TextBox>
// 空格不会保留
<TextBox>1 2 3 4
</TextBox>
使用代码控制XAML
// 加载XAML XamlReader
using(FileStream fs = new FileStream(xamlFile. FileMode.Open))
{rootElement = (DependencyObject)XamlReader.Load(fs);
}
// 查找元素方法1
button1 = (Button)LogicalTreeHelper.FindLogicalNode(rootElement, "button1");
// 查找元素方法2
FrameworkElement frameworkElement = (FrameworkElement)rootElement;
button1 = (Button)frameworkElement.FindName("button1");
注意事项
- 在XAML中加载的类,最好都能有一个无参数的构造函数,这样的类适合XAML的加载
WPF高级教程(三)XAML相关推荐
- DOS批处理高级教程(三) : 批处理变量和set命令详解
前言 这里主要是带着过一下相关的简单概念和用法, 是对于有一定的基础和编写脚本经验的同学而言, 那么一般下面的用法都是一眼看出作用和原理起到一个复习的作用.对于不熟悉的可以查询相关命令和百度即可. 第 ...
- WPF高级教程(一)概述
WPF是什么 WPF是基于Windows的用户界面框架,划重点:基于Windows,用户界面框架. 需要注意的是,WPF仅仅是有关于用户界面渲染的技术,而后台的开发,与系统的交互等都需要.NET Fr ...
- WPF入门教程系列三——Application介绍(续)
接上文WPF入门教程系列二--Application介绍,我们继续来学习Application 三.WPF应用程序的关闭 WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时,应用程序 ...
- WPF,Silverlight与XAML读书笔记第三十九 - 可视化效果之3D图形
原文:WPF,Silverlight与XAML读书笔记第三十九 - 可视化效果之3D图形 说明:本系列基本上是<WPF揭秘>的读书笔记.在结构安排与文章内容上参照<WPF揭秘> ...
- C语言高级教程-C语言数组(三)
C语言高级教程之数组教程 本文的编译环境 一.前文:C语言数组(一.二)的链接 1.1.C语言数组一文章链接 1.2.C语言数组二文章链接 二.数组的初始化 2.1.数组的初始化的几种方式 三.数组和 ...
- WPF教程三:布局之WrapPanel面板(转 )
WPF教程三:布局之WrapPanel面板 WrapPanel:环绕面板 WrapPanel布局面板将各个控件从左至右按照行或列的顺序罗列,当长度或高度不够时就会自动调整进行换行,后续排序按照从上至下 ...
- DOS批处理高级教程:第三章 FOR命令中的变量(转)
DOS批处理高级教程:第一章 批处理基础 DOS批处理高级教程:第二章 DOS循环for命令详解 DOS批处理高级教程:第三章 for命令中的变量 DOS批处理高级教程:第四章 批处理中的变量 DOS ...
- MongoDB 教程三: 高级查询 (SQL到MongoDB映射表)
查询接口 对于查询操作,MongoDB 提供了 db.collection.find() 方法.这个方法接收查询条件和映射两个条件并且返回一个指向匹配文档的 游标 .你可以使用 limits, ski ...
- MongoDB 教程三: 高级查询
视频:MongoDB 教程三: 高级查询 MongoDB支持的查询语言非常强大,语法规则类似于面向对象的查询语言,可以实现类似关系数据库单表查询的绝大部分功能,并且由于 MongoDB可以支持复杂的数 ...
- WPF入门教程系列四——Dispatcher介绍
WPF入门教程系列四--Dispatcher介绍 一.Dispatcher介绍 微软在WPF引入了Dispatcher,那么这个Dispatcher的主要作用是什么呢? 不管是WinForm应用程序还 ...
最新文章
- if for switch语句
- solidworks入门
- opencv4.4.0函数手册_Cobalt strike3.0使用手册
- mysql主主备份及集群
- IBM、甲骨文、CNCF 就谷歌对 Istio 治理的处理提出抗议
- Educational Codeforces Round 80 (Rated for Div. 2) E. Messenger Simulator 思维 + 树状数组
- Data Structure Problem
- 论文中常用的转折、连接词跟短语
- Android在Service中显示Dialog
- (21)System Verilog按时间顺序的通知需求(变量驱动)
- linux iio子系统
- Zookeeper-Paxos-屁民的故事-内含视频讲解
- 利用排序规则特点计算汉字笔划和取得拼音首字母
- 西电计算机学院通知,西安电子科技大学计算机科学与技术学院关于发放2020级硕士研究生正式录取通知书的通知...
- Dreamwear如何创建javascript_内存管理+如何处理4种常见的内存泄漏
- java 数值越界的判断_java 中int 范围越界校验算法
- 使用邮箱教学|邮箱是什么?办公中是怎么使用的
- SQL Server 2005 SP3正式版下载
- KusionStack 开源有感|历时两年,打破 “隔行如隔山” 困境
- layui card高度不匹配文字
热门文章
- 智能硬件再下一城:家居
- 2019最新《网易云课堂 C++收银系统项目实战教程》 C++开发网吧收银系统(MFC+ADO)
- 下载m3u8加密视频
- 2019商业数据分析软件有哪些
- 渗透之——网站入侵思路
- 利用DiskGenius对电脑磁盘系统数据迁移
- 使用 Wowza 录制直播流 (HTTPLiveStreamRecord)
- linux上的smartsvn图形客户端,linux 下svn图形客户端smartsvn 安装
- 计算机wifi无法打开,mac电脑wifi无法打开怎么解决-mac电脑wifi无法打开解决教程 - 河东软件园...
- 取石子游戏,威佐夫博弈的推理