【WPF标记扩展 】开篇 标记扩展
原文
阅读此文之前必备知识
类型转换器
XAML标记扩展定义
WPF 标记扩展 有哪些
WPF 编程中最常用的标记扩展是支持资源引用的标记扩展(StaticResource 和 DynamicResource)以及支持数据绑定的标记扩展 (Binding)。
多个 XAML 标记扩展是 XAML 2009 规范的一部分。 这些内容显示在具有自定义 x
命名空间前缀的 XAML 文件中,通常使用此前缀。
本文讨论以下标记扩展:
x:Static
– 引用静态属性、字段或枚举成员。x:Reference
– 引用页面上的命名元素。x:Type
– 将属性设置为System.Type
对象。x:Array
– 构造特定类型的对象的数组。x:Null
– 将属性设置为值null
。OnPlatform
– 基于每个平台自定义 UI 外观。OnIdiom
– 根据运行应用程序的设备的语态自定义 UI 外观。DataTemplate
– 将类型转换为DataTemplate
.FontImage
– 在任何可显示字体的视图中显示ImageSource
字体图标。AppThemeBinding
– 使用基于当前系统主题的资源。
其他 XAML 标记扩展历来受其他 XAML 实现的支持,也受 Xamarin.Forms支持。 其他文章更全面地介绍了这些内容:
StaticResource
- 引用资源字典中的对象,如 “资源字典”一文中所述。DynamicResource
- 响应资源字典中对象的更改,如 “动态样式”一文中所述。Binding
- 根据 数据绑定一文中所述,在两个对象的属性之间建立链接。TemplateBinding
- 从控件模板执行数据绑定,如文章 Xamarin.Forms 控件模板中所述。RelativeSource
- 设置绑定源相对于绑定目标的位置,如文章 相对绑定中所述。
布局 RelativeLayout
使用自定义标记扩展 ConstraintExpression
。 此标记扩展在 RelativeLayout 一文中介绍。
语法规则
语法一、当用于提供特性值时,将标记扩展序列与 XAML 处理器区分开的语法是左右大括号({ 和 })。 然后,由紧跟在左大括号后面的字符串标记来标识标记扩展的类型。
<Button Content = "{local:MyMarkupExtension FirstStr = Markup, SecondStr = Extension}" Width = "200" Height = "20" />
语法二、当用在属性元素语法中时,标记扩展在外观上与任何其他用于提供属性元素值的元素相同,即:一个将标记扩展类作为元素引用并以尖括号 (<>) 括起的 XAML 元素声明。
<TextBlock > <TextBlock.Text> <local:MyMarkupExtension FirstStr="MyMarkup1" SecondStr="Extension2"></local:MyMarkupExtension> </TextBlock.Text> </TextBlock>
语法三、缩写 、省略 Extension
<Button Content = "{local:MyMarkup FirstStr = Markup, SecondStr = Extension}" Width = "200" Height = "20" />
语法三、 省略 内容属性
<Label Text="{Binding Source={x:Reference Name=page} //Name
是内容属性 所以可以简写成
<Label Text="{Binding Source={x:Reference page}
代码
[ContentProperty("Name")]//Name
是内容属性
public class Reference : MarkupExtension
{
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public Reference();
public Reference(string name);
[ConstructorArgument("name")]
public string Name { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider);
}
内容属性需要类型转换器,而内容属性的含义就是在 Xaml 中,哪个属性可以直接表示该元素的内容。
<Button Content="Click Me!"/> <Button> <Button.Content> Click Me! </Button.Content> </Button> <Button> Click Me! 这就是内容转换器的功能 </Button>
用途
标记扩展基类
WPF
若要定义可与 System.Xaml 中的 XAML 读取器和 XAML 编写器的默认实现进行交互的自定义标记扩展,请从抽象的 MarkupExtension 类派生一个类。该类有一个要重写的方法,即 ProvideValue。您可能还需要定义其他构造函数来支持标记扩展用法的参数,并匹配可设置的属性。
Xamarin.Forms
IMarkupExtension 接口或IMarkupExtension<T>
接口,IMarkupExtension
两个接口只定义一个方法,分别命名ProvideValue
:
public interface IMarkupExtension { object ProvideValue(IServiceProvider serviceProvider); } public interface IMarkupExtension<out T> : IMarkupExtension { new T ProvideValue(IServiceProvider serviceProvider); }
自定义标记扩展
在上述XAML代码中,创建一个带有某些属性的按钮,对于内容值,自定义标记扩展名(My:MyMarkupExtension)已被分别用于分配给FirstStr和SecondStr的两个值“Markup”和“Extension”。
其实,MyMarkupExtension
是一个派生自MarkupExtension
C#实现中的下面的类。此类包含两个字符string变量FirstStr和SecondStr,它们连接并将该字符string从ProvideValue方法返回到按钮的内容。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Markup; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace XAMLMarkupExtension { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } } public class MyMarkupExtension : MarkupExtension { public MyMarkupExtension() { } public String FirstStr { get; set; } public String SecondStr { get; set; } public override object ProvideValue(IServiceProvider serviceProvider) { return FirstStr + " " + SecondStr; } } }
xaml中代码
<Window x:Class = "XAMLMarkupExtension.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:my = "clr-namespace:XAMLMarkupExtension" Title = "MainWindow" Height = "350" Width = "525"> <Grid> <Button Content = "{my:MyMarkupExtension FirstStr = Markup, SecondStr = Extension}" Width = "200" Height = "20" /> </Grid> </Window>
让我们来运行这个应用程序,您可以在MainWindow中立即看到“标记扩展名”已成功地用作按钮的内容。