2. XAML

用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#代码隐藏文件中使用:

    <StackPanel x:Name="stackPanel1">
        <Grid>
            <Button x:Name="button1" Content="Click Me!" Click="OnButtonClick"/>
        </Grid>
    </StackPanel>

在页面顶部,可以看到带有XML特性x:Class的Page袁术。这定义了类的名称,在该类中,XAML编译器生成了部分代码。使用Visual Studio中的代码隐藏文件,可以看到这个类中能修改的部分:

<Page
    x:Class="XAMLIntro.MainPage"
...
</Page>

代码隐藏文件包含类MainPage的一部分(XAML编译器没有生成这个部分)。在构造函数中,调用方法InitializeComponent。InitializeComponet的实现是由XAML编译器创建的。该方法加载XAML文件,并将其转换为XAML文件中的根元素指定的对象。OnButtonClick方法是之前在XAML代码中创建的按钮的Click事件处理程序。这个实现打开了一个MessageDialog:

        public MainPage()
        {
            this.InitializeComponent();
        }

        private async void OnButtonClick(object sender, RoutedEventArgs e)
        {
            await new MessageDialog("button 1 clicked").ShowAsync();
        }

现在,在C#代码的Button类中创建一个新对象,并将其添加到现有的StackPanel中。在下面的代码片段中,修改了MainPage的构造函数,以创建一个新按钮,设置Content属性,并为Click事件分配一个Lambda表达式。最后,新创建的按钮添加到StackPanel的Children中:

        public MainPage()
        {
            this.InitializeComponent();
            var button2 = new Button
            {
                Content = "created dynamically"
            };
            button2.Click += async (sender,e) =>
            {
                await new MessageDialog("button 2 clicked").ShowAsync();
            };
            stackPanel1.Children.Add(button2);
        }

如前所述,XAML只是处理对象、属性和事件的另一种方式。下一节将展示XAML在用户界面上的优势。

3. 通过XAML使用定制的.NET类

要在XAML代码中使用自定义的.NET类,可以使用简单的POCO类,对类定义没有特殊要求。只需要将.NET名称空间添加到XAML声明中。为了演示这一点,下面设计一个具有FirstName和LastName属性的简单Person类:

    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public override string ToString() =>
            $"{FirstName} {LastName}";
    }

在XAML中定义了一个名为datalib的XML的名称空间别名,它映射到程序集DataLib中的.NET名称空间DataLib。有了这个别名,现在就可以把别名作为元素前缀,来使用这个名称空间中的所有类。

在XAML代码中添加一个列表框,其中包含Person类型的项。使用XAML特性,可以设置属性FirstName和LastName的值。运行应用程序时,ToString()方法的输出显示在列表框中:

<Page
    x:Class="XAMLIntro.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:XAMLIntro"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:datalib="using:DataLib"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <StackPanel x:Name="stackPanel1">
        <Button x:Name="button1" Content="Click Me!" Click="OnB
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值