zoukankan      html  css  js  c++  java
  • MarkupExtension的使用

    记得第一次看到MarkupExtension是在几年前的一次面试中。很不好意思说,当时不知道是什么东东。最近在项目中又用到了WPF的这个功能,决定在博客里记录一下。

    在Xaml中为某个对象以Attribute的方式设置对象的属性时,attribute的值默认只能是字符串。例如:

    <TextBlock Text="Text"/>

    上面为Text属性设置值"Text"。如果属性的类型为String(如上面代码中的Text属性),这是没有问题的。但是如果属性的类型不是String,比如Foreground属性,它的类型是Brush。我们发现Xaml中仍然是可以通过设置一个字符串来完属性赋值的。例如:

    <TextBlock Foreground="Aqua" Text="Foreground"/>

    这是因为BCL为Brush类型定义了一个TypeConverter: BrushConverter. 它会在运行时将字符串转换成一个Brush结构。如果我们要在Xaml中直接给Foreground属性传递一个Brush对象怎么办呢?这就到了MarkupExtension发挥作用的时候了。它的作用就是扩充了Attribute方式赋值时只能赋给字符串的限制。让在赋值的时候可以执行后台代码从而产生所期望的对象。其实我们经常用的Binding,StaticResource,DynamicResource等都是属于MarkupExtension. 上代码:

    先看一下使用MarkupExtension后xaml的效果:

    <Window x:Class="WPFSample.Samples.MarkupExtensionSample"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:me="clr-namespace:WPFSample.Samples.MarkupExtensionSamples"
            Title="MarkupExtensionSample" Height="300" Width="300">
        <Grid>
            <StackPanel>
                <TextBlock Foreground="Aqua" Text="Foreground"/>
                <!--Following xaml code set a foreground using markup extension.-->
                <TextBlock Foreground="{me:BrushGetter TitleBrush}" Text="Foreground from markup extension"/>
                <TextBlock Foreground="{me:BrushGetter ContentBrush}" Text="Foreground from markup extension"/>
            </StackPanel>
        </Grid>
    </Window>

    再看看BrushGetter的定义:

    public class BrushGetter : MarkupExtension
        {
            private string _brushName;
    
            public BrushGetter(string brushName)
            {
                //在Xaml中使用该MarkupExtension时传递brushName参数。
                _brushName = brushName;
            }
    
            public override object ProvideValue(IServiceProvider serviceProvider)
            {
                //当在通过该MarkupExtension在Xaml中给属性赋值时,该方法将被调用。根据条件返回一个合适的对象即可。
                //至于参数serviceProvider,一般情况下用不到。暂时不纠结它了。
                switch (_brushName)
                {
                    case "TitleBrush":
                        return Brushes.Black;
                    case "ContentBrush":
                        return Brushes.Blue;
                    default:
                        break;
                }
    
                return null;
            }
        }

    最后看看最终效果:

    image

    其实使用MarkupExtension来赋值时,运行时会在每次赋值时构造一个Markup Extension对象,传递xaml中定义的参数,然后调用ProvideValue方法获取一个值。

  • 相关阅读:
    Balance_01背包
    4 Values whose Sum is 0_upper_bound&&ower_bound
    Newspaper Headline_set(upper_bound)
    lower_bound和upper_bound算法
    Blocks_DP&&矩阵快速幂
    All X_数的快速幂
    Training little cats_矩阵快速幂
    Raising Modulo Numbers_快速幂取模算法
    Defining Python Source Code Encodings
    Python ord(char)
  • 原文地址:https://www.cnblogs.com/Code-life/p/3463362.html
Copyright © 2011-2022 走看看