IExtenderProvider,c#组件扩展控件属性

[ProvideProperty("IsEnabled", typeof(LayoutControlItem)), ToolboxItemFilter("System.Windows.Forms"), Description("DevExpress自定义注册控件")]
    public partial class UserContorlEnabledClick : Component, IExtenderProvider
    {
        #region 构造函数
        private Hashtable items;//存放控件设置
        private Hashtable validateItems;

        public UserContorlEnabledClick()
        {
            InitializeComponent();
            items = new Hashtable();
            validateItems = new Hashtable();
        }

        public bool CanExtend(object extendee)
        {
            return true;
        }
        #endregion

        /// <summary>
        /// 显示自定义属性(Visual Studio设计器 IExtenderProvider接口方法)
        /// </summary>
        public RegexContext GetIsEnabled(LayoutControlItem control)
        {
            if (control == null)
            {
                throw new ArgumentNullException("LayoutControlItem");
            }
            RegexContext con = EnsurePropertiesExists(control);
            return con;
        }

        /// <summary>
        /// 设置自定义属性(Visual Studio设计器 IExtenderProvider接口方法)
        /// </summary>
        public void SetIsEnabled(LayoutControlItem control, RegexContext value)
        {
            RegexContext context = EnsurePropertiesExists(control);
            context.IsClick = value.IsClick;
            context.Validate = value.Validate;
            if (context.IsClick)
            {
                control.Click -= item_Click;
                control.Click += item_Click;
            }   
        }

        /// <summary>
        /// 确保扩展属性的菜单项在字典中
        /// </summary>
        /// <param name="key">目标菜单项</param>
        /// <returns>扩展属性</returns>
        private RegexContext EnsurePropertiesExists(object key)
        {
            RegexContext p;
            if (items.ContainsKey(key))
            {
                p = (RegexContext)items[key];
            }
            else
            {
                p = new RegexContext();
                items.Add(key, p);
            }
            if (!validateItems.ContainsKey(key))
            {
                validateItems.Add(key, p);
            }
            return p;
        }

        /// <summary>
        /// 点击事件
        /// </summary>
        private void item_Click(object sender, EventArgs e)
        {
            LayoutControlItem item = sender as LayoutControlItem;
            if (item == null) return;
            item.Control.Enabled = GetEnabled(item.Control.Enabled);
        }

        private bool GetEnabled(bool enabled)
        {
            if (enabled)
                return false;
            else
                return true;
        }

        //private void SetFromControl(Control control)
        //{
        //    var regexContext = userDXValidateExtender1.GetError(control);
        //    regexContext.AllowEmpty = !control.Enabled;
        //}
    }
    /// <summary>
    /// 属性
    /// </summary>
    [TypeConverter(typeof(ValidateTypeConverter)), ComVisible(true)]
    public class RegexContext
    {
        /// <summary>
        /// 异常信息
        /// </summary>
        private string _RegexExpression;
        [Category("验证"), DefaultValue(""), Description("设置异常信息")]
        public string RegexExpression
        {
            get { return _RegexExpression; }
            set { _RegexExpression = value; }
        }

        /// <summary>
        /// 是否注册点击事件
        /// </summary>
        private bool _isClick;
        [Category("验证"), DefaultValue(""), Description("设置点击事件enabled")]
        public bool IsClick
        {
            get { return _isClick; }
            set { _isClick = value; }
        }

        /// <summary>
        /// 是否验证控件
        /// </summary>
        private bool _Validate;
        [Category("验证"), DefaultValue(""), Description("设置验证控件不能为空")]
        public bool Validate
        {
            get { return _Validate; }
            set { _Validate = value; }
        }
    }

    public class ValidateTypeConverter : TypeConverter
    {
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            //如果目标类型是字符串,允许将自定义类型转换为字符串
            if (destinationType == typeof(string))
            {
                return true;
            }
            return base.CanConvertTo(context, destinationType);
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            //如果要转换为自定义类型
            if (destinationType == typeof(string))
            {
                if (value is RegexContext)
                {
                    RegexContext ca = (RegexContext)value;
                    return ca.RegexExpression;
                }
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }

        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return false;
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            string strValue = value as string;
            if (strValue != null)
            {
                string text = strValue.Trim();
                if (text.Length == 0)
                {
                    return null;
                }
                else
                {
                    RegexContext member = new RegexContext();
                    return member;
                }
            }
            return base.ConvertFrom(context, culture, value);
        }

        public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
        {
            if (propertyValues == null)
            {
                throw new ArgumentNullException("propertyValues");
            }
            object regexExString = propertyValues["RegexExpression"];
            object IsClick = propertyValues["IsClick"];
            object Validate = propertyValues["Validate"];
            RegexContext member = new RegexContext();
            member.RegexExpression = (string)regexExString;
            member.IsClick = (bool)IsClick;
            member.Validate = (bool)Validate;
            return member;
        }

        public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value,
                                                                   Attribute[] attributes)
        {
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(RegexContext), attributes);
            return props.Sort(new string[]
                {
                    "RegexExpression",
                    "IsClick",
                    "Validate"
                });
        }

        public override bool GetPropertiesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
    }
}

 

 

 

 

1UserContorlEnabledClick组件实现System.ComponentModel.IExtenderProvider接口,并继承System.ComponentModel.Component类,同时用ProvidePropertyAttribute特性描述该类。实现IExtenderProvider接口就表明本类是一个【扩展程序提供程序】,MSDN有相关的示例:http://msdn.microsoft.com/zh-cn/library/ms229066(v=vs.80).aspx。那么到底是要给什么类扩展出什么属性呢,这是由ProvideProperty特性定义的,本类的目的是为【UserContorlEnabledClick】类扩展出一个叫【IsEnabled】的属性,

继承Component则是为了让UserContorlEnabledClick像LayoutControlItem那样能拖入到VS组件栏中,这样LayoutControlItem的属性窗格中才会多出一个IsEnabled属性来。、

 

2、实现一个public string GetIsEnabled(LayoutControlItem control)方法,作用是获取指定控件,这也是第2步中定义容器的原因,没有容器记录下各个控件及其描述属性,这个方法将难以实现。注意该方法的命名必须是Get+ProvideProperty中定义的扩展属性名,即IsEnabled,合起来就是GetIsEnabled。另外,对该方法加DefaultValue特性是必要的,不然当拖入ToolDescribe时,VS会对所有item进行扩展,不管有没有设置某个item的Describe,这点可以从InitializeComponent方法中看出来;

 

3、实现一个public void SetIsEnabled(LayoutControlItem control, RegexContext value)方法,命名要求同上。该方法的作用注册事件或设置属性和添加到容器里(Hashtable)。

 

4、自定义属性RegexContext类,及自定ValidateTypeConverter类(这个特性十分重要,可以让属性折叠显示),

效果图

 我是参考大佬的博客https://www.cnblogs.com/ahdung/p/4169724.html,嘻嘻嘻

posted @ 2019-04-19 10:42  世人皆萌  阅读(556)  评论(0编辑  收藏  举报