• WpfMarkupExtension学习笔记


    MarkupExtension:msdn上定义:

    为可以由 .NET Framework XAML 服务及其 XAML 读取器和 XAML 编写器支持的 XAML 标记扩展实现提供基类。

    个人使用下来的感觉有点类似于附加属性,但是附加属性是用来定义的赋值的,而该扩展类可以用来作为变量绑定附加属性或者依赖属性。

    每个继承MarkupExtension的类都需要override一个方法:

    public override object ProvideValue(
                                   IServiceProvider serviceProvider)

    当中参数IServiceProvider serviceProvider可以提供一个object GetService(Type serviceType);方法:

    具体使用:

     IProvideValueTarget ipvt =
                    (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
    
    DependencyObject targetObject = ipvt.TargetObject as DependencyObject;
    DependencyProperty dp = ipvt.TargetProperty as DependencyProperty;

    通过该方法,可以获取绑定的控件,以及绑定的属性。

    同时可以定义多个属性,以及对应的构造函数,配合设计模型需要。

    public MaxValueExtensionFull(object value1, object value2)
            {
                Value1 = value1;
                Value2 = value2;
            }
    
            [ConstructorArgument("value1")]
            public object Value1 { get; set; }
    
            [ConstructorArgument("value2")]
            public object Value2 { get; set; }

    好了定义了这么多,为的是什么呢?接下来可以为我们的扩展xaml添加逻辑内容了:

    private object GetMaxValue()
            {
                if (Value1 is IComparable && Value1 is IComparable)
                {
                    if (((IComparable)Value1).CompareTo(Value2) >= 0)
                        return Value1;
                    else
                        return Value2;
                }
                else
                {
                    // use val1
                    return Value1;
                }
            }
    
            public override object ProvideValue(IServiceProvider serviceProvider)
            {
                if (serviceProvider == null)
                    return null;
    
                // get the target of the extension from the IServiceProvider interface
                IProvideValueTarget ipvt =
                    (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
    
                DependencyObject targetObject = ipvt.TargetObject as DependencyObject;
    
                object val = GetMaxValue();
    
                if (ipvt.TargetProperty is DependencyProperty)
                {
                    // target property is a DP
                    DependencyProperty dp = ipvt.TargetProperty as DependencyProperty;
    
                    if (val is IConvertible)
                    {
                        val = Convert.ChangeType(val, dp.PropertyType);
                    }
                }
                else
                {
                    // target property is not a DP, it's PropertyInfo instead.
                    PropertyInfo info = ipvt.TargetProperty as PropertyInfo;
    
                    if (val is IConvertible)
                    {
                        val = Convert.ChangeType(val, info.PropertyType);
                    }
                }
    
                return val;
            }

    刚开始这么写扩展,觉得有些多余,我可以在控件上加依赖属性,加converter转换,一样可以绑定,但是这样子的话一个控件就要一堆属性和converter,代码冗余。

    而使用扩展后,我只需要定义一个Extension,那么就可以在所有控件上都使用了。

  • 相关阅读:
    RESTClient使用
    web.xml 的加载过程
    I18N、L10N、G11N
    Oracle游标示例
    MyEclipse转换Eclipse项目无法启动问题(转)
    eclipse默认文件编码
    JAVA为什么要配置环境变量,怎样配置
    TODO Auto-generated method stub
    vc6开发ActiveX并发布全攻略(三)(转)
    高效使用hibernate-validator校验框架
  • 原文地址:https://www.cnblogs.com/gavinhuang/p/3305352.html
Copyright © 2020-2023  润新知