• [.NET] XAML(2)标签扩充


    前言

    在前一个章节[.NET] XAML(1)--对象生成,介绍了「XAML对象生成」这个简单却强大的对象生成模式。透过这个XAML对象生成配合面向对象的对象设计,可以让开发人员依照XAML内容生成近乎无限组合的对象。但是光只有前一个章节介绍的内容,在实际的开发应用上,很快就会遇到不足的地方。

    假设现在要使用Property-Element的设定,将TextBlock 的Text设定为.NET里的Null,开发人员可能会写出下面范例的XAML。

    <TextBlock x:Name="ShowTextBlock" FontSize="72">
        <TextBlock.Text>
            Null
        </TextBlock.Text>
    </TextBlock>
    

    这段XAML乍看之下很合理,但是照前一章的运作逻辑去做分析。.NET剖析XAML Element来产生对象的时候,会将"Null"转换为字符串,而不会是开发人员预期的.NET里面的Null。由这一个简单的范例来理解,就可以发现Property-Attribute、Property-Element…等等,的确是有语意不足的地方。

    Markup Extensions

    为了补足Property-Attribute、Property-Element这些设定语意不足的地方,XAML另外提供了「标记延伸」(Markup Extensions)这个设定,来满足开发人员的需求。Markup Extensions的运作逻辑,主要是围绕在MarkupExtension这个Class身上。

    当程序使用.NET剖析XAML Object-Element建立对象的时候,会特别去检查建立出来的对象,是不是继承自MarkupExtension的子对象型别。当发现建立的对象是继承自MarkupExtension的子对象型别,.NET不会用这个对象当作Object-Element建立的结果,而是改呼叫这个对象继承与覆写的MarkupExtension的ProvideValue方法。并且使用ProvideValue方法的回传值,当作Object-Element建立的结果对象。

    我们可以建立范例,来验证Markup Extensions的运作逻辑。首先建立一个继承自MarkupExtension的子对象类别ClarkExtension,并且覆写继承自MarkupExtension的ProvideValue方法。在这个范例里,ClarkExtension的ProvideValue方法只是单纯的回传一个"Clark"字符串。

    using System;
    using System.Windows.Markup;
    using System.Windows.Media;
    
    namespace WpfApplication2
    {
        public class ClarkExtension : MarkupExtension
        {
            public ClarkExtension()
            {
    
            }
    
            public override object ProvideValue(IServiceProvider serviceProvider)
            {
                return "Clark";
            }
        }
    }
    

    接着建立XAML范例,来使用ClarkExtension这个Class。下面这段XAML,采用Property-Element来将ClarkExtension,设定为TextBlock对象的Text属性。

    <Window x:Class="WpfApplication2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:sample="clr-namespace:WpfApplication2"
            Title="MainWindow" Height="400" Width="240">
        
        <TextBlock x:Name="ShowTextBlock" FontSize="72">
            <TextBlock.Text>
                <sample:ClarkExtension />
            </TextBlock.Text>
        </TextBlock>
        
    </Window>
    

    将这个范例编译执行,并且在程序代码里加入断点来检视对象执行的顺序。可以发现的确是执行了ClarkExtension的建构子之后,就呼叫ProvideValue、回传Clark字符串。并且在执行之后,将Clark字符串设定为TextBlock 的Text内容,这样最终程序呈现的执行结果就会如下图。透过这个范例,开发人员可以简单验证与理解XAML的 Markup Extensions运作逻辑。

    相关数据可以参考:
    http://msdn.microsoft.com/zh-tw/library/ee855815.aspx
    http://msdn.microsoft.com/zh-tw/library/system.windows.markup.markupextension.aspx

    简化语法

    上一个章节XAML范例里的Markup Extensions设定,看起来跟一般常见的XAML上的Markup Extensions有所出入,一整个复杂了许多,这对于开发人员来说并不是很友善的设计。为了降低复杂度及提高可读性,XAML另外加入了简化的语法设定,让XAML的设计可以变得更简洁。

    首先XAML定义了MarkupExtension对象,可以省略撰写Extension后置字符。以上一个章节的范例来说,可以将范例XAML里的TextBlock简化设定为:

    <TextBlock x:Name="ShowTextBlock" FontSize="72">
        <TextBlock.Text>
            <sample:Clark />
        </TextBlock.Text>
    </TextBlock>
    

    另外使用Property-Attribute设定的时候,XAML也定义使用大括号 ({...}),来识别MarkupExtension对象。以上一个章节的范例来说,可以将范例XAML里的TextBlock简化设定为:

    <TextBlock x:Name="ShowTextBlock" FontSize="72" Text="{sample:ClarkExtension}"/>
    

    当然啦,这两个简化的规则是可以互相组合的。以上一个章节的范例来说,可以将范例XAML里的TextBlock简化设定为如下的结果。这样的简化结果,就是一般常见的XAML设定。

    <TextBlock x:Name="ShowTextBlock" FontSize="72" Text="{sample:Clark}"/>
    

    相关数据可以参考:
    http://msdn.microsoft.com/zh-tw/library/ee855815.aspx#naming_the_support_type
    http://msdn.microsoft.com/zh-tw/library/ms788723.aspx#markup_extensions

    XAML 定义标记延伸

    在XAML内对于一些常见的的使用情景,预先实做了几个MarkupExtension子对象。这些预设的MarkupExtension子对象,通常放在System.Xaml组件的System.Windows.Markup命名空间内。在使用Visual Studio建立XAML相关页面的时候,要引用这些MarkupExtension子对象,预设是以「x: 前导符」来加以引用。几个比较常见的XAML MarkupExtension如下:

    x:Type (TypeExtension)
    TypeExtension会剖析设定的参数数据,回传对应的 Type对象。

    x:Static(StaticExtension)
    StaticExtension会剖析设定的参数数据,回传对应的对象的静态属性。

    x:Null(NullExtension)
    NullExtension没有需要设定的参数数据,就只是单纯的回传.NET的Null物件。

    更多的数据可以参考:
    http://msdn.microsoft.com/zh-tw/library/ms747254.aspx#XAML_Defined_Markup_Extensions

    后记

    XAML的Markup Extensions这个设定,是一些WPF、Silverlight、WP7功能(数据系结、资源参考)的运作核心。先理解Markup Extensions这个运作核心的职责及工作内容,再去学习数据系结、资源参考功能。这样从运作核心本身开始学习的路线,会比较正确而且快速、并且不会被过多繁杂的变化所迷惑。

    补充

    XAML在WPF、Silverlight、WP7都可以使用,但不同目标平台所开放、支持的函式库却不一定相同。以本章说明的StaticExtension来说,这个MarkupExtension类别在WPF上有支持,但在WP7上却是不支持的(撰写本文时,开发环境安装的是Windows Phone SDK 7.1)。开发人员在撰写XAML的时候,先确认目标平台支持的函式库相关内容,可以减少一些开发上不必要的困扰。


  • 相关阅读:
    从零开始学SQLSERVER-游标CURSOR(基础)
    从零开始学SQLSERVER-创建表
    从零开始学HTML-button
    从零开始学前端HTML-input标签
    专项测试实战 | 如何测试 App 流畅度(基于 FPS 和丢帧率)
    接口测试框架实战 | 流程封装与基于加密接口的测试用例设计
    软件测试之30分钟轻松搞定正则表达式基础
    Python 装饰器填坑指南 | 最常见的报错信息、原因和解决方案
    react16与react15之间的区别
    react-父子组件之间的交互传值
  • 原文地址:https://www.cnblogs.com/clark159/p/2461501.html
Copyright © 2020-2023  润新知