• 零起点学习WPF之《WPF揭秘》读书笔记(3)


    2.8 编译:将XAML代码与过程式代码混合使用。【数据绑定特性 和 触发器】

    2.8.1在运行时加载和解析XAML

    WPF的运行时XAML解释器公开为两个类,他们都在System.Windows.Markup命名空间下,分别为:XamlReader和XamlWriter 。XamlReader中包含一些Load方法的重载,XamlWriter包含一些Save方法的重载。

    (1)XamlReader
    XamlReader .Load 方法的设置将解析Xaml,创建合适的.NET对象,然后返回一个根元素的实例。
    例如:在当前的目录中有一个一个名为:MyWindows.xaml,它包含一个Window对象作为根节点,那么可以使用下面的代码来加载和获取Windows对象。

    Window window =null;
    Using(FileStream fs = newFileStream("MyWindow.xaml"),FileMode.Open,FileAccess.Read)
    {
         window =(Window)XamlReader.Load(fs);//获得根元素
    }
    在上述的情况下:Load与FileStream 一起被调用的。在load返回之后,整个XAML文件的对象层级将在内存中被实例化,因此就不在需要XAML文件了。

    【提示】XamlReader 也提供了LoadAsync方法,用以异步加载和解析XAML文档,CancelAsync和Completeted方法用以辅助LoadAsync方法。


    既然有一个根对象元素的实例存在,就可以利用适当的内容元素或者是集合元素,下面的代码假设Window有一个类行为StackPanel 的子元素,StackPanel 的第5个子对象是一个OK Button.

    Windowwindow = null;
    Using(FileStream fs = newFileStream("MyWindow.xaml"),FileMode.Open,FileAccess.Read)
    {
         window =(Window)XamlReader.Load(fs);
    }

    通过硬编码的方式获取Button按钮
    StackPanel panel =(Stackpanel)window.Content;

    Button okButton = (Button)panel.Children[4];//第五个子对象为Button

    有了这个Button按钮我们就可以做我们想做的事了,例如:设置额外的属性,添加事件处理程序,执行一些无法用XAML完成的动作。


    当然、用硬编码的索引和其他用户界面结构的代码并不能让人满意,因为稍微修改一下XAML它便无法正常工作了。相反,我们可以用比较通用方式编写一些代码来找到那个内容为OK字符串的Button按钮,但是对于如此简单的任务来说,这样做就有些得不偿失了。另外、如果我们想要找到包含图形元素的Button,那我们该怎么办呢!?

    幸运的是,XAML中支持元素命名,这样我们就可以在过程式的代码中轻松的找到他们、并使用他们了。

    命名XAML元素

    在XAML语言的命名空间中有一个Name关键字,它是用来给元素命名的,如果是一个嵌入到窗体中的简单的OK按钮,其中的Name关键字可以这样使用。

    <Button x:Name = "OKButton">OK</Button>
    有了上述的元素命名之后,我们就可以利用Window的FindName方法(递归)的寻找到元素名称为okButton的元素了。

    Window window = null;
    Using(FileStream fs = newFileStream("MyWindow.xaml"),FileMode.Open,FileAccess.Read)
    {
         window =(Window)XamlReader.Load(fs);
    }
    Button okButton = (Button)window.FindName("okButton");

    FindName 不仅仅是在Window中有,而且在FrameworkElement、FrameworkContentElement及许多重要的WPF类的基类中都有FindName方法的定义。

    不用x:Name  也能命名元素
    用x:Name 可以命名元素,但是一些类中可以定义自己的属性用来作为元素的名称(这需通过添加System.Windows.Markup.RuntimeNamePropertyAttribute特性来实现)。
    例如:在FrameworkElement 和 FrameworkContenElement 因为他们有一个Name 属性,所以他们的声明中加入了一个RuntimeNamepropertyAttribute("Name")语句。这样也就意味着:只用一个字符串我们就可以设置Name属性了,而不需要再用x:Name语法了。可以使用其中的任何一中机制,但是不能同时使用他们,


    2.8.2 编译XMAL

    XAML编译编译包括三项事情:(1)将XAML转换成一种特殊的二进制格式,(2)将转换好的内容做为二进制资源嵌入到正在被创建的程序集中,(3)执行链接操作,将XAML与过程式代码自动连接起来。

    如果想要编译一个XAML文件,我们需要做的第一个工作就是为XAML文件的根元素指定一个子类,可以使用XAML命名空间的Class 关键字来完成,例如:

    <Window xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml
            x:Class ="MyNameSpace.MyWindow">
    //其他
    </Window>

    在一个独立的源文件中,但是在同一个项目中,可以添加一个子类,可以添加任何你想添加的成员,例如
    Namespace MyNameSpace

        pritial ClassMyWindow:Window
        {
             public MyWindow()
             {
                  //一定要调用的,只有调用了之后才可以加载XAML中的内容
                 InitializeCompenent();
             }
             Any Other members can gohere
        }

    通常我们叫上述的代码文件叫做代码隐藏文件,如果你引用XAML中的任何一个事件处理程序,(通过事件特性、例如Button的Click特性,在代码隐藏文件里就是定义事件处理程序的地方。


    (1)生成的源代码
    【提示】x:Class 只能在要编译的XAML文件中使用,但是在没有x:Class的情况下 XAML文件也是可以被编译的,只是没有x:Class代表着它没有对应的代码隐藏文件而已。
    还有注意:不要忘记在隐藏代码文件的构造函数中调用  InitializeCompenent();



    返回导读目录,阅读更多随笔



    分割线,以下为博客签名:

    软件臭虫情未了
    • 编码一分钟
    • 测试十年功


    随笔如有错误或不恰当之处、为希望不误导他人,望大侠们给予批评指正。

  • 相关阅读:
    ASP.NET Core结合Nacos来完成配置管理和服务发现
    一次业务网关用ASP.NET Core 2.1重构的小结
    给HttpClient添加请求头(HttpClientFactory)
    使用Redis实现最近N条数据的决策
    记一次Python与C#的AES加密对接
    按次计费接口的简单实现思路
    .NET Core 3 WPF MVVM框架 Prism系列文章索引
    异步函数async await在wpf都做了什么?
    .NET Core 3 WPF MVVM框架 Prism系列之对话框服务
    .NET Core 3 WPF MVVM框架 Prism系列之导航系统
  • 原文地址:https://www.cnblogs.com/08shiyan/p/1818152.html
Copyright © 2020-2023  润新知