[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 == )
{
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;
}
}
}

1、让UserContorlEnabledClick组件实现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,嘻嘻嘻

IExtenderProvider,c#组件扩展控件属性的更多相关文章

  1. ExtJs控件属性配置详细

    序言:    1.本文摘自网络,看控件命名像是4.0以前的版本,但控件属性配置仍然可以借鉴(不足之处,以后项目用到时再续完善). Ext.form.TimeField: 配置项:            ...

  2. Android控件属性大全(转)

    http://blog.csdn.net/pku_android/article/details/7365685 LinearLayout         线性布局        子元素任意: Tab ...

  3. FoxOne---一个快速高效的BS框架--WEB控件属性编辑器

    FoxOne---一个快速高效的BS框架--(1) FoxOne---一个快速高效的BS框架--(2) FoxOne---一个快速高效的BS框架--(3) FoxOne---一个快速高效的BS框架-- ...

  4. Android控件属性大全[整理转载]

    控件属性: android属性 Android功能强大,界面华丽,但是众多的布局属性就害苦了开发者,下面这篇文章结合了网上不少资料, 第一类:属性值为true或falseandroid:layout_ ...

  5. 【转载】Android控件属性大全

    控件属性: android属性 Android功能强大,界面华丽,但是众多的布局属性就害苦了开发者,下面这篇文章结合了网上不少资料, 第一类:属性值为true或falseandroid:layout_ ...

  6. DELPHI控件属性事件说明

    常用DELPHI控件属性事件设置说明 常用DELPHI控件属性设置说明目录TForm Class TPanel组件 TToolBar Class TToolButton Class TTimer Cl ...

  7. 43. ExtJs控件属性配置详细

    转自:https://www.cnblogs.com/mannixiang/p/6558225.html 序言:    1.本文摘自网络,看控件命名像是4.0以前的版本,但控件属性配置仍然可以借鉴(不 ...

  8. 2.C#Panel扩展控件

    1.解决方案下添加新建项目新建类库 2. 在项目下添加新建项选择新建组件类 3.先引用,然后导入两个命名空间 4.因为是扩展控件,把继承自Component改成继承自Panel using Syste ...

  9. 多年前写的文本框扩展控件(有ValueChanging事件等),已放github

    本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 阅读目录 介绍 起因 代码 使用 GitHub ...

随机推荐

  1. MySQL 5.7新增加的json数据类型

    MySQL 5.7中有json存储类型了以前我们只能通过php来进行序列化了不过现在就不需要了我们可以直接使用MySQL 5.7的json数据类型来存储json格式数据了,具体来看介绍.   在MyS ...

  2. Ubuntu 18.04系统下arm-linux-gcc交叉编译器安装

    Ubuntu 18.04系统: arm-linux-gcc 4.4.3版本. 安装arm-linux-gcc将压缩包arm-linux-gcc.tar.gz解压到arm-linux-gcc文件夹tar ...

  3. IP拨号器

    是一个最终的接收者 package com.example.ip; import android.content.BroadcastReceiver; import android.content.C ...

  4. C++ unique

    #include <iostream>#include <algorithm>#include <list>#include <iterator>#in ...

  5. Python基础-day04

    函数基础 目标 函数的快速体验 函数的基本使用 函数的参数 函数的返回值 函数的嵌套调用 在模块中定义函数 01. 函数的快速体验 1.1 快速体验 所谓函数,就是把 具有独立功能的代码块 组织为一个 ...

  6. 【ARTS】01_24_左耳听风-201900422~2019004028

    ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...

  7. linux 文件赋权限

    chown tomcat:tomcat /logs chmod 766 /logs

  8. Go单引号和双引号区别

    首先做个测试,看下面那个选项是正确的: A. str:='abc'+'123'B. str:="abc"+"123"C. str:='123'+"ab ...

  9. Cocos Creator 中的动作系统那些事儿

    动作系统就是可以在一定的时间内实现位移.旋转.缩放.跳动等各种动作. 需要注意的是,动作系统跟 Cocos Creator 编译器的动画系统不同,动作系统是面向程序员的API接口,而动画系统是通过编译 ...

  10. Unity爬坑记录-Sprite 相关功能Editor、打包器等无法使用

    找了好久的问题,同一个Unity,但是不同项目,一个没问题,一个出现上面情况.