我们在编程控件(Control)或者是组件(Component)的时候总是要暴露一些属性(Property,不同于Attribute)给用户进行配置,以得到可以变化的功能。

mapserver .NET组件编程(1) 基础 中说到的

1、Component在Run Time时不能呈现UI,而Control可以在Run Time时呈现UI(但是vs 2005里的asp.net中的SqlDataSource是Control,但是它不能呈现UI)。
2、Component是贴在容器Container上的,而Control则是贴在Windows Form或者Web Form上的。 举例来说,SqlCommand是个Component,DataGrid则是一个Control。

mapserver写了.net 组件编程系列,值得看看。

就说,如何在设计时对某个属性(property)提供一些帮助,那么就需要用到几个重要的属性(Attribute)。

TypeConverter, Editor 标签属性

下面ImageIndex的属性被贴上标签属性。

   1: [//TypeConverter(typeof(ImageIndexConverter)),
   2: Editor(typeof(newimageEditoer), typeof(UITypeEditor)),
   3: Description("")]
   4:       public int ImageIndex
   5:       {
   6:           get { return myVar; }
   7:           set { myVar = value; }
   8:       }

TypeConverter 指类型转换。

Editor 在设计时,调用哪个Editor对它进行编辑修改。

DesignerSerializationVisibilityAttribute:指定通过Property Editor得到的结果是否保存在代码中。
LocalizableAttribute:用户要本地化某个窗体时,任何具有该特性的属性都将自动永久驻留到资源文件中。

*注意
TypeConverter 和 Editor有时候是相互作用的。比如上面的例子,大家可以用reflector看看微软的buttonBase 里面的ImageIndex的标签属性是什么,并找到ImageIndexConverter 和对应的Editor [ImageIndexEditor]。 如果我们继续是用TypeConverter[ImageIndexConverter ],重新完成一个新的Editor[newimageEditoer],你会发现新的Editor是不起作用的。

接下来,我们看看Serializable标签属性会在VS自动代码起到什么样的作用,接着,我们再回过头看看ButtonBase里面ImageIndex属性怎么通过在标签属性TypeConverter 和Editor配合下,我们就能在设计的时候选择button对应的图片的?

Serializable 标签属性
   1: [Serializable]
   2:    public class XButton  
   3:    {

注意,如果贴上Serilizable,则代码会自动生成(来之与from1.designer.cs文件的片段)

   1: this.userControl11.xButtons.Add(((WindowsControlLibrary1.XButton)(resources.GetObject("userControl11.xButtons"))));

也就说它是通过从资源文件来保存(序列)值。如果不贴上[Serializable]标签,则自动生成在代码里面(来之与from1.designer.cs文件的片段)

   1: //先实例
   2: WindowsControlLibrary1.XButton xButton1 = new WindowsControlLibrary1.XButton();
   3: WindowsControlLibrary1.XButton xButton2 = new WindowsControlLibrary1.XButton();
   4: //
   5: xButton1.component = null;
   6: xButton1.ImageIndex = -1;
   7: xButton2.component = null;
   8: xButton2.ImageIndex = -1;
   9: this.userControl11.xButtons.Add(xButton1);
  10: this.userControl11.xButtons.Add(xButton2);

描述一下xButton类, xButtons是一个List<xButton>集合类型。

   1: public class XButton  
   2:  
   3:  
   4:    public XButton()
   5:    {
   6:         
   7:    }
   8:  
   9:    private string _txt = "";
  10:    [DefaultValue("")]
  11:    public string Text
  12:    {
  13:        get { return _txt; }
  14:        set { _txt = value; }
  15:    }
  16:  
  17:    private int myVar = -1;
  18:  
  19:    [//TypeConverter(typeof(ImageIndexConverter)),
  20: r(typeof(newimageEditoer), typeof(UITypeEditor)),
  21: iption("")]
  22:    public int ImageIndex
  23:    {
  24:        get { return myVar; }
  25:        set { myVar = value; }
  26:    }
  27:  
  28:    [NonSerialized]
  29:    private System.ComponentModel.Component _im;
  30:    [Browsable(false)]          
  31:    public System.ComponentModel.Component  component
  32:    {
  33:        get { return _im; }
  34:        set { _im = value; }
  35:    }
  36:  
  37:    

ButtonBase里面ImageIndex属性怎么通过在标签属性TypeConverter 和Editor配合下,我们就能在设计的时候选择button对应的图片的?

先看看UI,一开始,我以为Editor是完成了所有编辑功能(编辑样式[EditStyle]你可以选择三种,一种none,一种是下拉框,一种是对话框形式)

这个可以在继承UITypeEditor类复写

   1: public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
   2: {
   3:  
   4:     return UITypeEditorEditStyle.Modal;
   5:     //return base.GetEditStyle(context);
   6: }

那么,我们是如何看到下拉框图片的呢?本来我以为这部分会在Editor里面实现,实际上不是的。有部分是在ImageIndexConverter中,它创建了Image的Collection

   1: public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
   2:         {
   3:             if ((context != null) && (context.Instance != null))
   4:             {
   5:                 object instance = context.Instance;
   6:                 PropertyDescriptor imageListProperty = ImageListUtils2.GetImageListProperty(context.PropertyDescriptor, ref instance);
   7:                 while ((instance != null) && (imageListProperty == null))
   8:                 {
   9:                     PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(instance);
  10:                     foreach (PropertyDescriptor descriptor2 in properties)
  11:                     {
  12:                         if (typeof(ImageList).IsAssignableFrom(descriptor2.PropertyType))
  13:                         {
  14:                             imageListProperty = descriptor2;
  15:                             break;
  16:                         }
  17:                     }
  18:                     if (imageListProperty == null)
  19:                     {
  20:                         PropertyDescriptor descriptor3 = properties[this.ParentImageListProperty];
  21:                         if (descriptor3 != null)
  22:                         {
  23:                             instance = descriptor3.GetValue(instance);
  24:                             continue;
  25:                         }
  26:                         instance = null;
  27:                     }
  28:                 }
  29:                 if (imageListProperty != null)
  30:                 {
  31:                     ImageList list = (ImageList)imageListProperty.GetValue(instance);
  32:                     if (list != null)
  33:                     {
  34:                         object[] objArray;
  35:                         int count = list.Images.Count;
  36:                         if (this.IncludeNoneAsStandardValue)
  37:                         {
  38:                             objArray = new object[count + 1];
  39:                             objArray[count] = -1;
  40:                         }
  41:                         else
  42:                         {
  43:                             objArray = new object[count];
  44:                         }
  45:                         for (int i = 0; i < count; i++)
  46:                         {
  47:                             objArray[i] = i;
  48:                         }
  49:                         return new TypeConverter.StandardValuesCollection(objArray);
  50:                     }
  51:                 }
  52:             }
  53:             if (this.IncludeNoneAsStandardValue)
  54:             {
  55:                 return new TypeConverter.StandardValuesCollection(new object[] { -1 });
  56:             }
  57:             return new TypeConverter.StandardValuesCollection(new object[0]);
  58:         }

里面的实际上用了反射的机制来获取一个ImageList并把其中的Image加入到一个TypeConverter.StandardValuesCollection,但具体是谁来控制把这集合显示出来的呢?我不知道。

至于把它显示出来是在Editor里面实现的,其中调用了方法GetImage,就是去找到Image并画出来。

   1: public override void PaintValue(PaintValueEventArgs e)
   2:         {
   3:             if (this.ImageEditor != null)
   4:             {
   5:                 Image image = null;
   6:                 if (e.Value is int)
   7:                 {
   8:                     image = this.GetImage(e.Context, (int)e.Value, null, true);
   9:                 }
  10:                 else if (e.Value is string)
  11:                 {
  12:                     image = this.GetImage(e.Context, -1, (string)e.Value, false);
  13:                 }
  14:                 if (image != null)
  15:                 {
  16:                     this.ImageEditor.PaintValue(new PaintValueEventArgs(e.Context, image, e.Graphics, e.Bounds));
  17:                 }
  18:             }
  19:         }

关于这方面的一些资料

编写与.NET属性窗口交互的RAD组件

其中有一段话,我很感兴趣

在实现数据绑定的组件中,清除掉DataSource的值,自然的就会清除掉DataMember的值。RefreshPropertiesAttribute就让我们实现这个功能。他的默认值是“none,”不过如果指定其他的特性,属性窗口就可以在改变这个属性值的同时,自动的更新被更新属性的值。另外的两个值是Repaint,它让属性窗口重新获取属性的值并且重画他们,还有就是All,它就意味着组件自己要重新获取属性的值。如果值的改变导致属性的数目的增减,那么我们就要使用All。不过要注意到这个一般用在高级场合,并且速度要比Repaint慢。RefreshProperties.Repaint适用于大部分的情况。

所谓的刷新调用的是什么方法来进行? 比如,我设置了某个属性的值,这个属性的值又是关于空间外观的,那么如何来触发这个事件?

转载于:https://www.cnblogs.com/king_astar/archive/2008/05/05/1183678.html

编写windows 控件需要注意的几个标签属性(Attribute)相关推荐

  1. 用C#编写ActiveX控件(三) 转载

    在前面我们已经完成了ActiveX控件的开发,接下来的就是发布它了. 首先,我们建立一个windows安装项目,并将ActiveX控件的主输出添加到项目输出中.然后,改动ActiveX控件的主输出文件 ...

  2. 利用ArcGIS Engine、VS .NET和Windows控件开发GIS应用

    Dixon 原文  用ArcGIS Engine.VS .NET和Windows控件开发GIS应用 此过程说明适合那些使用.NET建立和部署应用的开发者,它描述了使用ArcGIS控件建立和部署应用的方 ...

  3. [转]用C#编写ActiveX控件(一)

    前些日子做一个Web项目,必须自己编写一个ActiveX控件.如今的ActiveX控件大多是使用VB/C++来开发的,而我对他们并不熟悉,因此考虑使用熟悉的C#编写ActiveX控件. 首先,建立一个 ...

  4. 关于用C#编写ActiveX控件4(转)

    在前面我们已经完成了ActiveX控件的开发,接下来的就是发布它了. 首先,我们建立一个windows安装项目,并将ActiveX控件的主输出添加到项目输出中.然后,改动ActiveX控件的主输出文件 ...

  5. 关于用C#编写ActiveX控件2(转)

        了解了上述相关的理论之后,我们来看一个用C#编写ActiveX的实例. 首先,建立一个WinForm控件项目HelloWorld,并拖入一个Label控件,文字设为HelloWorld,如图: ...

  6. 用C#编写ActiveX控件,开发浏览器控件,注册ActiveX 控件

    用C#编写ActiveX控件,开发浏览器控件,注册ActiveX 控件 用C#编写ActiveX控件 开发浏览器控件这是本控件开发完成后的一个简单应用.我们可以利用它以本地文件夹为单位来批量更新服务器 ...

  7. Unity 工具控件 之 Text 文本字间距调整(老版本的Unity编写工具控件/新版本Unity使用TMP)

    Unity 工具控件 之 Text 文本字间距调整(老版本的Unity编写工具控件/新版本Unity使用TMP) 目录 Unity 工具控件 之 Text 文本字间距调整(老版本的Unity编写工具控 ...

  8. 关于《用C#编写ActiveX控件》的几点说明

    在我的第一篇blog发表之后,得到大家的支持,我的工作得到了认可,感到很开心.当然,很多朋友也提出了很多出色的见地.我想在这里说明一下我对这些问题的理解.         我所完成的控件是一个用来获取 ...

  9. 关于 LDTP 操纵 windows 控件。

    LDTP doc: https://ldtp.freedesktop.org/user-doc/ 对于 web 自动化,我们用 Selenium, 但是对于 windows 控件,我们可以使用 LDT ...

最新文章

  1. Win2008学习(二),群集的仲裁配置
  2. java中的关键字static
  3. SqlServer修改数据库文件及日志文件存放位置
  4. 观看5万个游戏视频后,英伟达AI学会了自己开发「吃豆人」
  5. 计算机应用基础2010一级,2010年一级结构基础辅导:(计算机应用基础)备考讲义(10)...
  6. 网卡驱动:stmmac DMA发送流程
  7. SQL Server--通过存储过程生成表数据的脚本
  8. 02工厂模式+抽象工厂模式(创建型模式)
  9. GitHub 超 20000 Star,最火开源视频库 FFmpeg 这 20 年!
  10. python天下第一什么梗_「PHP 是最好的语言」这个梗是怎么来的?
  11. 英语翻译软件测试简历,如此翻译-2 - Victor's Testing Career - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
  12. 信捷XD/XC系列PLC 控制台达B2系列伺服电机程序,手动 自动,循环,循环次数设定
  13. 年底知识「大甩卖」,知识付费这杯羹还有的分吗?
  14. 科三——细则以及扣分点
  15. linux下木马程序病原体的制作和运行
  16. 计算机视觉研究院手把手教你深度学习的部署(手势识别,源码已开源)
  17. C#语言实例源码系列-自定义ListBox背景
  18. 流氓软件“实名制” 午夜影院乔装正规军
  19. body 没有被撑开_flex布局被子元素撑开如何保持内容不超出容器的方法
  20. 2D/3D加速器概念

热门文章

  1. 【工具】13 款 Linux 实用工具推荐,个个是神器!(附下载链接)
  2. 从零开始入门 K8s | Kata Containers 创始人带你入门安全容器技术
  3. er图用什么软件_从软件开发生命周期看商业智能 BI 数据仓库建模
  4. android preference tab,Android SharedPreference - TabHost问题
  5. oracle z中rowid,如何将索引块里面的rowid和表里面的rowid对应起来?
  6. vc 获取月份的天数_「青少年编程」课程:输入年份与月份,得到该月有多少天...
  7. 3 v4 中心节点固定_科研人员提出新型水声网络移动节点接入协议
  8. 给图片加一层半透明_设计半透明风格卡通星球图片的PS教程
  9. d-s 多传感器信息融合 matlab实现_自动驾驶中的多传感器融合
  10. 【AI白身境】学AI必备的python基础