zoukankan      html  css  js  c++  java
  • WPF教程一:创建Hello world来理解XAML的内容及编译

      在实际的WPF开发中遇到很多再用Winform写法来写WPF的开发人员,很多时候项目进度延期、出现非必要的BUG等等、大多是因为开发人员虽然是再写WPF。

    但是没有好好的学过WPF,就导致无法发挥出WPF的优势、很多地方都是开个线程处理完成后一个回调UI线程函数里面套一整段代码,这种情况下不仅难处理多线程问题、也会出现很多偶发性的BUG,不好追踪问题在哪里。同时也会因为开发人员对WPF的理解参差不齐导致架构设计和使用过程中代码凌乱。所以今天开始hello world 来梳理WPF。

    我们通过hello world理解以下几个关键内容来整理XAML相关的知识点:

    一、使用XAML创建可以显示hello world的文本框。

    二、理解XAML中的文法规范级命名空间

    三、XAML中的的属性和事件

    四、从生成过程日志查看XAML的编译。

     

    一、使用XAML创建可以显示hello world的文本框

      经常写winform窗体的同学一定深有感触、拿到UI给的图之后、我们如果想做的比较漂亮。大部分都是通过拖控件、然后把用户界面的后台代码中设置动画效果、大小、位置等等。如果需要适配多种分辨率是更难受的。特别是一些需要深度定制的东西、可能很多开发时间都会用在这里。解决一些稀奇古怪被测试出来的的显示问题。

      而在WPF中提出了XAML的概念、我们可以使用XAML标签来设计和构成我们的用户界面。而XAML丰富的标签一旦正确的使用,则会大大提高我们写出更漂亮的界面的能力。

    只写文字大家都会反感。我们通过讲解例子来认识XAML。首先创建一个WPF工程。

    1、写下第一行Hello world

    打开VS选择创建WPF项目,点击下一步。

    设置项目名称为Hello World点击创建。就创建了我们第一个WPF项目。

     通过解决方案标签项我们可以看到整个解决方案的目录结构。而项目中的MainWindow就是我们本次分析的重点。

     

     我们这次的重点在MainWindow.xaml和其对应的cs,所以其他部分不是本次的关注重点,也就不讲了。

    首先双击MainWindow.xaml,在Grid标签中添加<TextBox Text="Hello world!"/>节点。然后在VS中按下F5键。程序就会执行编译,如果成功的话就会跑起来,并且看到我们输入的Hello world!。

    <Window x:Class="HelloWorld.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:HelloWorld"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <TextBox Text="Hello world!"/>
        </Grid>
    </Window>

    从我们看到这个显示出来的hello world!的这一刻开始,就正式开始了本章内容的讲解。 

    二、理解XAML中的文法规范级命名空间

     1 <Window x:Class="HelloWorld.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     6         xmlns:local="clr-namespace:HelloWorld"
     7         mc:Ignorable="d"
     8         Title="MainWindow" Height="450" Width="800">
     9     <Grid>
    10         <TextBox Text="Hello world!"/>
    11     </Grid>
    12 </Window>

    为了方便理解,我加入了行号,如果想系统的学习XAML可以先学习一下XML,XAML是遵循XML文法规范的,但是对于我们入门来说了解嵌套、 属性的赋值和设置,就可以了。

    我们的整体XAML结构大致为

    <Window>
    
      <Grid>
    
        <TextBox/>
    
      </Grid>
    
    </Window>

    我们当前的XAML根节点是一个Window节点,Window节点代表当前所显示的整个窗口、在Window节点内部有一个Grid节点,Grid节点是一个布局元素里面可以放置的所有的控件、Grid节点包含了一个内部的TextBox节点,而这个TextBox就是我们所说的控件,而我们看到的显示的内容是在Text=“”内赋值的。对于XAML中的内容。可以理解为把后台的.cs代码文件通过xaml可视化的方式进行设置,如果有不知道含义的地方,可以用鼠标点在对应的节点上然后按F12就可以跳转到对应的定义中。

      比如我们把光标点在Grid上。按下F12。就会跳转到下图的位置。原来Grid继承自一个Panel。里面包含了Column、Row等等。我们就知道了。Grid是一个拥有横、列的网格面板。

     而在TextBox上按F12之后,就会看到这是一个控件、显示或编辑文本的。

    其他的元素同样的道理。把鼠标放置在对应的元素节点上按下F12就会显示对应的内容。

     

    接下来我们来看命名空间。

    名称空间看上去好像是一个URI的WEB位置,但实际上不是,URI格式的命名空间,不同组织就基本不会使用相同的名称空间创建不同的基于XAML的语言。

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 是WPF核心名称空间。 它包含了所有WPF类,包括创建界面的控件。
    该名称空间没有使用前缀、所以它成为整个文档的默认命名空间。也就是说除非指明了名称空间,否则每个元素都直接使用这个名称空间。
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 是XAML名称空间,它包含各种XAML的特性,该命名空间被映射为前缀x。可以在元素名称之前放置x
    来使用该名称空间。例如x:Name,x:Class="HelloWorld.MainWindow"。
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"是旨在提供设计师支持,该名称空间使XAML元素上的这些属性仅影响XAML行为的设计方面。
    而在运行过程中会忽略掉这些属性。比如d:DesignHeight="100" d:DesignWidth="100",这个在设计时看不到该控件时,在对应的控件上添加此属性特别有效。
    在Blend下使用比较多的是针对集合的d:DataContext、d:DesignData。等等。感兴趣的可以看看Blend相关的。
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 标识使运行时XAML解析器能够忽略设计属性,比如mc:Ignorable:d。d前缀的在运行时XAML解析器解析时就会忽略了。
    xmlns:local="clr-namespace:HelloWorld" 这个就是我们工程自己的名称空间了。

    x:Class="HelloWorld.MainWindow" x:Class特性是告诉XAML解析器用指定的名称生成一个新类,该类继承自XAML元素命名的类,也就是我们的根节点Window。

    三、理解XAML中的的属性和事件

     XAML中的属性:

    我们通过前面的讲解了通过跳转查看XAML节点的含义,比如<Grid>是布局用的Panel。<TextBox/>是显示和编辑无格式文本的。
    那么现在我们来理解属性。
    在元素中我们通过跳转了解到了XAML节点都是一个一个的类对象。里面定义了属性、方法及事件。那么在XAML中,我们可以在这里设置属性、事件。通过设置这些来修改样式及监听对应的事件消息。
    那么在属性中分为简单属性和复杂属性。我们在Textbox上按F12跳转过去,然后我们找个属性来演示一下简单属性和复杂属性如何使用。

     

     在Foreground上我们看到了该属性是一个Brush类型。而在WPF中Brush支持纯色、线性渐变色等等。我们设置代码如下。

     这样我们就在第一个TextBox 上设置了背景色为一个枚举值。用于表示一个颜色值。 而当我们想设置复杂Brush的时候,我们就可以使用复杂属性,第二个TextBox通过属性的嵌套来创建一个复杂的线性画刷。2个TextBox显示效果如下:

      

     但是新的问题又来了,现在大部分主流的App都支持更换皮肤,明暗主题什么的。而我们只能通过硬编码的形式设置属性,那岂不是要实现更换皮肤,每个控件都要设置一遍?

    有没有什么办法能让XAML属性绑定一个变量,而我们去修改这个变量?

    实现方法的办法之一就是使用扩展标记:假设我们的内容都放在一个windows里做演示:

     

     添加window的资源。同时使用DynamicResource来绑定资源。就可以实现。一个资源修改,所有使用的地方都跟着变化。后面会详细讲到。如何使用扩展标记来进行主题切换。

    而在WPF中提出的是依赖项属性的概念。这个和路由事件需要花费精力好好学一下。才能更好的使用和理解WPF。

     XAML中的事件:

    为了增强事件的传播能力,WPF中提出了路由事件的概念,路由事件可以在元素树中向上和向下传播,并且沿着传播路径被事件处理程序消费。我们在XAML中添加2个处理按下和抬起事件的代码。

     

    后台的处理代码。

      

     路由事件和依赖项属性这些主要会放在MVVM中讲。这里主要了解一下。XAML下如何创建事件处理程序。

    四、从生成过程日志查看XAML的编译。

    对于加载和编译XAML,有四种方式:

    1、只使用代码来创建XAML对应的元素,类似于winform的写法;

    2、使用代码和未经编译的XAML。

    3、使用代码和编译过的XAML。

    4、只使用XAML。

    这里我们只去理解一个使用代码和编译过的XAML。其他的工作到目前未知,觉得用到的比较少,等真正用到了。只要理解了可以在去查如何使用。

    当我们编译WPF程序时,编译过程分为了2个阶段,第一个个阶段是将XAML文件编译为BAML文件。我们使用的C#语言,所以会在临时文件生成对应的.g.cs文件

    g代表generated。

    当从XAML到BAML的编译结束后,编译器会编译代码和生成的部分类文件。编译过的代码会变成单个程序集。每个窗口的BAML都会作为独立资源被嵌入到程序集中。

    我们通过修改VS的设置来查看编译过程。

    在VS选择工具=>选项=>项目和解决方案=>生成并运行=>MSBuild项目生成输出详细程序=>设置为详细。而后点击编译。我们来观察输出的内容。

     

    我们查看关键的几处

     

      

     

    以上截图就是完整的编译过程。

    我创建了一个C#相关的交流群。用于分享学习资料和讨论问题。欢迎有兴趣的小伙伴:QQ群:542633085

  • 相关阅读:
    SQL Server 数据库镜像
    SQL Server跨服务器查询
    doi
    通过Http接口及SolrNet 两种方法基于Solr5.5.1 实现CURD
    调整SQLServer最大服务器内存参数后实例停止且无法启动
    在windows server 2012/2016上,任务管理器性能页面增加磁盘监控的办法
    Windows Server 2016 启用完整版任务管理器
    solr如何让全词匹配结果在最前面
    C#的两种类据类型:值类型和引用类型
    Web of Science API
  • 原文地址:https://www.cnblogs.com/duwenlong/p/14424000.html
Copyright © 2011-2022 走看看