精选文章 2. XAML

2. XAML

作者:singhwong 时间: 2021-02-05 09:43:34
singhwong 2021-02-05 09:43:34
【摘要】用ASP.NET Core编写Web应用程序时,除了需要知道C#之外,还需要了解HTML、CSS和JavaScript。创建Windows应用程序时,除了C#之外,还需要了解XAML。XAML不仅用于创建Windows应用程序,还用于Windows Presentation Foundation(WPF)、Windows WorkFlow Foundation(WCF)和Xamarin的跨平...

用ASP.NET Core编写Web应用程序时,除了需要知道C#之外,还需要了解HTML、CSS和JavaScript。创建Windows应用程序时,除了C#之外,还需要了解XAML。XAML不仅用于创建Windows应用程序,还用于Windows Presentation Foundation(WPF)、Windows WorkFlow Foundation(WCF)和Xamarin的跨平台应用程序。

可以用XAML完成的工作都可以用C#实现,每个XAML元素都用一个类表示,因此可以从C#中访问。那么,为什么还需要XAML?XAML通常用于描述对象及其属性,可以描述很深的层析结构。例如,Page包含一个Grid控件,Grid控件包含一个StackPanel和其他控件,StackPanel包含按钮和文本框控件。XAML便于描述这种层析结构,并通过XML特性或元素分配对象的属性。

XAML允许以声明的方式编写代码,而C#主要是一种命令式编程语言。XAML支持声明式定义。在命令式编程语言(如C#)中,用C#代码定义一个for循环,编译器就使用中间语言(IL)代码创建一个for循环。在声明性编程语言中,声明应该做什么,而不是如何完成。

注意:

虽然C#不是纯粹的命令式编程语言,但使用LINQ时,也是在以声明方式编写语法。Entity Framework Core(EF Core)的LINQ提供程序将LINQ查询转换为SQL语句。

XAML是一个XML语法,但它定义了XML的几个增强特性。XAML仍然是有效的XML。但是一些增强特性有特殊的意义和特殊的功能,例如,在XML特性中使用花括号,对于XML,这仍然只是一个字符串,因此是有效的XML。对于XAML,这是一个标记扩展。

在有效使用XAML之前,需要了解这门语言的一些重要特性。本章介绍了如下XAML特性:

  • 依赖属性:从外部看起来,依赖属性像正常属性。然而,它们需要更少的存储空间,实现了变更通知。
  • 路由事件:从外部看起来,路由事件像正常的.NET事件。然而,通过添加和删除访问器来使用自定义事件实现方式,就允许冒泡和隧道。事件从外部控件进入内部控件称为隧道,从内部控件进入外部控件称为冒泡。
  • 附加属性:通过附加属性,可以给其他控件添加属性。例如,按钮控件没有属性用于把它自己定位在Grid控件的特性行和列上。在XAML中,看起来有这样一个属性。
  • 标记扩展:编写XML特性需要的编码比编写XML元素少。然而,XML特性只能是字符串;使用XML元素可以编写更强大的语法。为了减少需要编写的代码量,标记扩展允许在特性中编写强大的语法。

1. XAML标准

WPF、UWP和Xamarin对XAML元素使用(部分仍然使用)不同的语法。例如,对于WPF和UWP,按钮有Content属性,而Xamarin的按钮有Text属性。在WPF和UWP中,可以使用StackPanle来排列多个元素。在Xamarin中,类似的控件是StackLayout。

为了更容易地在不同的UI技术堆栈之间切换,定义了XAML标准。有关标准的实际状态,请参见 https://github.com/Microsoft/xaml-standard/

2. 将元素映射到类

在每个XAML元素的后面都有一个具有属性、方法和事件爱你的类。如前所述,可以使用C#代码或使用XAML创建UI元素。下面看一个例子。使用以下代码片段,定义了一个包含按钮控件的StakcPanel。使用XAML特性,按钮分配了Content属性和Click事件。Content属性只包含一个简单的字符串,而Click事件引用了方法OnButtonClick的地址。XML特性x:Name用于向按钮控件声明一个名词,该名称可以在XAML和C#代码隐藏文件中使用:

   

 使用元素代替特性,可以把比较复杂的画笔应用于Background属性(LinearGradientBrush),如下面的示例所示。

 

注意:

当设置示例中的内容时,Content特性和Button.Content元素都不用于编写内容;相反,内容会直接写入为Button元素的子元素值。这是因为在Button类的基类ContentControl中,ContentProperty特性通过[ContentProperty("Content")]应用,这个特性把Content属性标记为ContentProperty。这样,XAML元素的直接子元素就应用于Content属性。

3. 依赖属性

XAML使用依赖属性完成数据绑定、动画、属性变更通知、样式化等。依赖属性存在的原因是什么、假设创建一个类,它有100个int类型的属性,这个类在一个表单上实例化乐100次。需要多少内存?因为int的大小是4个字节,所以结果是4*100*100=40 000字节。刚才看到的是一个XAML元素的属性?由于继承层次结构非常大,一个XAML元素定义了数以百计的属性。属性类型不是简单的int,而是更复杂的类型。这样的属性会消耗大量的内存。然而,通常只改变其中一些属性的值,大部分的属性保持对所有实例都相同的默认值。这个难题可以用依赖属性解决。使用依赖属性,对象内存不是分配给每个属性和实例。依赖属性系统管理一个包含所有属性的字典,只有值发生了改变才分配内存。否则,默认值就下所有实例之间共享。

依赖属性也内置了属性变更通知的支持。对于普通属性,需要为属性变更通知实现INotifyPropertyChanged接口。这种变更机制是通过依赖属性内置的。对于数据绑定,绑定到.NET属性源上的UI元素必须是依赖属性。现在,详细讨论依赖属性。

从外部来看,依赖属性像是正常的.NET属性。但是,正常的.NET属性通常还定义了由该属性的get和set访问器访问的数据成员。

 private int _value; public int Value { get => _value; set => _value = value; }

依赖属性不是这样。依赖属性通常也有get和set访问器。它们与普通属性是相同的。但在get和set访问器的实现代码中,调用了GetValue()和SetValue()方法。GetValue()和SetValue()方法是基类DependencyObject的成员,依赖对象需要使用这个类——它们必须在DependencyObject的派生类中实现。

有了依赖属性,数据成员就放在由基类管理的内部集合中,仅在值发生变化时分配数据。对于没有变化的值,数据可以在不同的实例或基类之间共享。GetValue()和SetValue()方法需要一个DependencyObject参数。这个参数由类的一个静态成员定义,该静态成员与属性同名,并在该属性名的后面追加Property术语。对于Value属性,静态成员的名称是ValueProperty。DependencyProperty.Register()是一个辅助方法,可在依赖属性系统中注册属性。在下面的代码片段中,使用Register()方法和4个参数定义了属性名、属性的类型和拥有者的类型(即MyDependencyObject类),使用PerpertyMetadata指定了默认值。

 public class MyDependencyObject:DependencyObject { public int Value { get => (int)GetValue(valueProperty); set => SetValue(valueProperty,value); } public static readonly DependencyProperty valueProperty = DependencyProperty.Register("Value",typeof(int), typeof(MyDependencyObject),new PropertyMetadata(0)); }

7. 创建依赖属性

下面的示例定义的不是一个依赖属性,而是3个依赖属性。MyDependencyObject类定义了依赖属性Value、Minimum和Maximum。所有这些属性都是用DependencyProperty.Register()方法注册的依赖属性。GetValue()和SetValue()方法是基类DependencyObject的成员。对于Minimum和Maximum属性,定义了默认值,用DependencyProperty.Register()方法设置该默认值,可以把第4个参数设置为PropertyMetadata。使用带一个参数PropertyMetadata的构造函数,把Minimum属性设置为0,把Maximum属性设置为100。

 public class MyDependencyObject : DependencyObject { public int Value { get => (int)GetValue(ValueProperty); set => SetValue(ValueProperty, value); } public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(int), typeof(MyDependencyObject), new PropertyMetadata(0)); public int Minimum { get => (int)GetValue(MinimumPropety); set => SetValue(MinimumPropety, value); } public static readonly DependencyProperty MinimumPropety = DependencyProperty.Register(nameof(Minimum), typeof(int), typeof(MyDependencyObject), new PropertyMetadata(0)); public int Maximum { get => (int)GetValue(MaximumProperty); set => SetValue(MaximumProperty, value); } public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register(nameof(Maximum), typeof(int), typeof(MyDependencyObject), new PropertyMetadata(100)); }

注意:

在get和set属性访问器的实现代码中,只能调用GetValue()和SetValue()方法。使用依赖属性,可以通过GetValue()和SetValue()方法从外部访问属性的值。UWP也是这样作的。因此,强类型化的属性访问器可能根本就不会被调用,包含它们仅为了方便在自定义代码中使用正常的属性语法。

8. 值变更回调和事件

为了获得值变更的信息,依赖属性还支持值变更回调。在属性发生变化时调用的DependencyProperty.Register()方法中,可以添加一个DependencyPropertyChanged事件处理程序。在示例代码中,把OnValueChanged()处理程序方法赋予PropertyMetadata对象的PropertyChangedCallback属性。在OnValueChanged()方法中,可以用DependencyPropertyChangedEventArgs()参数访问属性的新旧值。

 public int Value { get => (int)GetValue(ValueProperty); set => SetValue(ValueProperty, value); } public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(int), typeof(MyDependencyObject), new PropertyMetadata(0,OnValueChanged)); private static void OnValueChanged(DependencyObject obj,DependencyPropertyChangedEventArgs e) { int oldValue = (int)e.OldValue; int newValue = (int)e.NewValue; }

9. 路由事件

使用默认实现的事件,当触发事件时,将调用直接连接到事件的处理程序。使用UI技术时,对事件处理有不同的需求。在一些事件中,应该可以创建一个带有容器控件的处理程序,并对来自子控件的事件做出反应。这可以通过为.NET事件创建自定义实现代码来实现,如add和remove访问器所示。

UWP提供了路由事件。示例应用程序定义的用户界面包含一个复选框,如果选中它,就停止路由;一个按钮控件,其Tapped事件设置为OnTappedButton处理程序方法;一个网格,其Tapped事件设置为OnTappedGrid处理程序。Tapped事件是Universal Windows应用程序的一个路由事件。这个事件可以用鼠标、触摸屏和笔设备触发:

         
勿删,copyright占位
分享文章到微博
分享文章到朋友圈

上一篇:QT5 之HTTP -GET/POST请求

下一篇:【面试题Part 3】: Linux

您可能感兴趣

  • memcached全面剖析–2. 理解memcached的内存存储

    2019独角兽企业重金招聘Python工程师标准>>> 下面是《memcached全面剖析》的第二部分。 发表日:2008/7/9 作者:前坂徹(Toru Maesaka) 原文链接:http://gihyo.jp/dev/feature/01/memcached/0002 我是mixi株式会社研究开发组的前坂徹。 上次的文章介绍了memcached是分布式的高速缓存服务器。 本...

  • 【S1】2.生命周期相关 & something

    本文仅给出可能性以便查阅。生命周期非常重要,故不再细说。 1. 实现监听Button的方法有四种 匿名内部类直接实现,即用即销毁。activity继承onClickListener接口,实现onClick(View v);Button安装监听器为this。单独实现,另写一个类实现listener配置实现,在layout文件中配置,并在java文件中写出该类。 2. 熟识生命周期七个...

  • 《Programming WPF》翻译 第5章 2.内嵌样式

    原文:《Programming WPF》翻译 第5章 2.内嵌样式 每一个“可样式化”的WPF元素都有一个Style属性,可以在内部设置这个属性——使用XAML属性-元素的语法(在第一章讨论的),如示例5-4。 示例5-4 <Button  x:Name="cell00" />  <Button.Style>    <Style>      <Setter Property="But...

  • windows10UWP:如何在xaml中设置控件为 public ?

    windows10UWP中,由于使用页面导航,操作在不同一个页面的控件需求经常遇到。 如果要对另一个page里面的控件进行操作,那么这个控件必须设置为 public .在 xaml 设置控件的方法是:    就是 x:FieldModifier="public" 。详细可以查看:https://msdn.microsoft.com/zh-cn/library/a...

  • 简单介绍如何使用PowerMock和Mockito来mock 1. 构造函数 2. 静态函数 3. 枚举实现的单例 4. 选择参数值做为函数的返回值(转)...

    本文将简单介绍如何使用PowerMock和Mockito来mock1. 构造函数2. 静态函数3. 枚举实现的单例4. 选择参数值做为函数的返回值5. 在调用mock出来的方法中,改变方法参数的值一点简要说明:Mockito其实已经可以满足大部分的需求,但是它的实现机制是使用cglib来动态创建接口的类的实例。但是这种实现方式不能用于构造函数和静态函数,因为那需要使用类的字节码(比如使用ja...

  • WPF在XAML中Binding使用StringFormat属性

    原文: WPF在XAML中Binding使用StringFormat属性 1、绑定Currency,如果没有字符的话,后面需要先加入{},不加的话会出问题 2、绑定Currency,并在前面加入一些字符,跟上面相比,没有{}3、绑定日期4、绑定时间5、多重绑定 6、多重绑定中的特殊字符,如 \t 特殊字符如下: \a    BEL \b    BS - Bac...

  • 2.编码方式

    1.ASC - 7位代表一个字符,128个 2.ASCII - 8位代表一个字符,256个 3.MBCS编码族   DBCS - 单双字节混合编码方式(计算机的主流编码方式):英文占1个字节,中文占2个字节。   例如:A      我      是      程      序      员              01   0203  0405  0607  0809...

  • 2.盘点springmvc的常用接口之HandlerMethodReturnValueHandler

    2019独角兽企业重金招聘Python工程师标准>>> 2.盘点springmvc的常用接口之HandlerMethodReturnValueHandler### 前言 上一章中介绍了HandlerMethodArgumentResolver来处理controller方法的参数绑定问题。一个请求中有入参的绑定处理,那么当然也会有响应参数的处理,这一章就来讲讲处理返回对象的接口——or...

CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
2. XAML介绍:华为云为您免费提供2. XAML在博客、论坛、帮助中心等栏目的相关文章,同时还可以通过 站内搜索 查询更多2. XAML的相关内容。| 移动地址: 2. XAML | 写博客