自定义组件之属性(Property)的性质(Attribute)介绍(四)

二:UI属性编辑器(UITypeEditor)

这里的属性编辑器的意思是能够实现上面提到的弹出对话框和下拉UI的形式。废话不说下面我们一一介绍。

1、 弹出对话框的形式

在本例中我使用了string类型的属性来显示版本的信息,大家可以随便的写各类的属性,这里只需要指定改属性的编辑器就可以了。

首先我们要建立一个string类型的属性,代码如下:

private string _appVer="1.0";

[CategoryAttribute("自定义编辑器"),

DefaultValueAttribute("1.0"),

DescriptionAttribute("版本信息"),

ReadOnlyAttribute(true),

EditorAttribute(typeof(AppVerConverter),typeof(System.Drawing.Design.UITypeEditor))]

public string AppVer

{

get {return this._appVer;}

set {this._appVer=value;}

}

大家可能已经注意到了在这个属性之多出了一个性质EditorAttribute(typeof(AppVerConverter),typeof(System.Drawing.Design.UITypeEditor)),具体的意思大家可以参考MSDN我在这里就不用多说了,那么我们看看AppVerConverter这个类是怎么实现的就可以了。具体代码如下:

/// <summary>

/// 自定义UI的属性编辑器(弹出消息)

/// </summary>

public class AppVerConverter:System.Drawing.Design.UITypeEditor

{

/// <summary>

/// 覆盖此方法以返回编辑器的类型。

/// </summary>

public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)

{

return System.Drawing.Design.UITypeEditorEditStyle.Modal;

}

/// <summary>

/// 覆盖此方法以显示版本信息

/// </summary>

public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)

{

System.Windows.Forms.MessageBox.Show("版本:1.0\n作者:张翔","版本信息");

return value;

}

}

这里需要说明的是我们的属性编辑器必须从System.Drawing.Design.UITypeEditor继承,要不然就不能显示UI了。UITypeEditorEditStyle方法的返回值决定了改属性编辑器的类型大家可以参考msdn我在这里就不多说了。编译之后就可以看到如下的画面了:

2、 下拉UI的类型

下拉UI类型主要是提供给用户一个简单的界面来选择所要确定的属性,这种方式提供给用户非常友好的界面。下面的例子我们首先定义里一个Point类型的属性,在默认的情况下这种类型的属性是会以展开的形式来让用户编辑的。在这里我们扩展了他的功能,不仅仅能通过直接输入的方式来改变值,而且还可以下拉出来一个控件,用户可以在这个控件上根据鼠标的位置来确定具体的值。下面具体的代码:

private System.Drawing.Point _dropUI;

[CategoryAttribute("自定义编辑器"),

DefaultValueAttribute("1"),

DescriptionAttribute("下拉可视控件"),

ReadOnlyAttribute(false),

EditorAttribute(typeof(DropEditor),typeof(System.Drawing.Design.UITypeEditor))]

public System.Drawing.Point DropUI

{

get { return this._dropUI;}

set { this._dropUI=value; }

}

public class DropEditor:System.Drawing.Design.UITypeEditor

{

public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)

{

return System.Drawing.Design.UITypeEditorEditStyle.DropDown;

}

public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)

{

System.Windows.Forms.Design.IWindowsFormsEditorService iws=(System.Windows.Forms.Design.IWindowsFormsEditorService)provider.GetService(typeof(System.Windows.Forms.Design.IWindowsFormsEditorService));

if (iws!=null)

{

PropertyGridApp.DropUIControl UIControl=new PropertyGridApp.DropUIControl((System.Drawing.Point)value,iws);

iws.DropDownControl(UIControl);

return UIControl.Value;

}

return value;

}

}

internal class DropUIControl:System.Windows.Forms.UserControl

{

public DropUIControl(System.Drawing.Point avalue,System.Windows.Forms.Design.IWindowsFormsEditorService iws)

{

this.Value=avalue;

this._tmpvalue=avalue;

this._iws=iws;

this.SetStyle(System.Windows.Forms.ControlStyles.DoubleBuffer|System.Windows.Forms.ControlStyles.UserPaint|System.Windows.Forms.ControlStyles.AllPaintingInWmPaint,true);

this.BackColor=System.Drawing.SystemColors.Control;

}

private System.Drawing.Point _value;

public System.Drawing.Point Value

{

get { return this._value;}

set { this._value=value; }

}

private System.Drawing.Point _tmpvalue;

private System.Windows.Forms.Design.IWindowsFormsEditorService _iws;

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)

{

string str="X:"+this._tmpvalue.X.ToString()+" ;Y:"+this._tmpvalue.Y.ToString();

System.Drawing.Graphics g=e.Graphics;

System.Drawing.SizeF sizef= g.MeasureString(str,this.Font);

g.DrawString(str,

this.Font,

new System.Drawing.SolidBrush(System.Drawing.Color.Black),

(int)((this.Width-(int)sizef.Width)/2),

this.Height-(int)sizef.Height);

g.PageUnit=System.Drawing.GraphicsUnit.Pixel;

g.FillEllipse(new System.Drawing.SolidBrush(System.Drawing.Color.Red),

this.Value.X-2,

this.Value.Y-2,

4,

4);

}

protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)

{

base.OnMouseMove(e);

this._tmpvalue=new System.Drawing.Point(e.X,e.Y);

this.Invalidate();

}

protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e)

{

base.OnMouseUp(e);

this.Value=this._tmpvalue;

this.Invalidate();

if (e.Button==System.Windows.Forms.MouseButtons.Left)

this._iws.CloseDropDown();

}

}

以上的代码度非常的简单,相信大家一定能够看懂,如果有不明白的地方看看帮助,那里面解释的非常的清楚。

在编写属性编辑器中我们都需要覆盖其中的EditValue这个方法,大家是否注意到了其中的object Value这个参数?其实这个参数就是已经装箱的属性值,在我们自定义的处理完这个值的时候同样可以返回一个装箱的值来确定已经修改的属性。在上面的两个例子中我们只是简单的使用了这个值,大家理解这个内容之后就可以做出更加个性化的编辑器了。

时间: 2016-02-06

自定义组件之属性(Property)的性质(Attribute)介绍(四)的相关文章

自定义组件之属性(Property)的性质(Attribute)介绍(一)

自定义组件之 属性(Property)的性质(Attribute)介绍 属性(property)作为c#语言中一个重要的组成部分,尤其是在我们自己编写组件的时候显得更加重要.我相信大家一定对其有一定的了解.但是大家是否注意到了一个非常关键得细节问题呢?那就是在大家使用任何得组件的时候都需要通过属性浏览器给每一属性赋值,而且更加友好的是对于每种不同类型属性都会自己的形式.比如:数字类型.字符串类型是默认简单的输入的形式,而如Font.Color类型的属性则可以对话框或下拉列表框的形式.不知道大家是

自定义组件之属性(Property)的性质(Attribute)介绍(三)

2.展开的形式 展开的形式多用于一个属性为我们自定义类的类型,比如我们定义了一个类,该类中的一个属性是另一个我们定义的类.在这种情况下属性浏览器默认是没有办法来进行类型转换的,所以显示为不可编辑的内容.如果我们要以展开的形式编辑这个属性就需要我们向上面一样来重写属性转换器. 我们首先定义一个自己的类来作为以后的属性类型.具体代码如下: public class ExpandProperty { private int _intList=0; public int IntList { get {

自定义组件之属性(Property)的性质(Attribute)介绍(二)

一:属性转换器(TypeConverter) 1. 下拉列表框的形式: 要使用下拉列表框的形式的属性我们首先要定义一个属性,在这个例子中我定义了一个字符串类型的属性 FileName. private string _fileName; public string FileName { get { return this._fileName;} set { this._fileName=value; } } 定义完属性之后,我们还要自己一个属性转换器.那么什么是属性转换器呢?其实在属性浏览器中只

Android 自定义组件卫星菜单的实现

卫星菜单 ArcMenu 相信大家接触安卓,从新手到入门的过渡,就应该会了解到卫星菜单.抽屉.Xutils.Coolmenu.一些大神封装好的一些组件.这些组件在 Github 上面很容易搜得到,但是有时候打开会发现看不懂里面的代码,包括一些方法和函数 ..... 首先先上效果图: 实现效果 首先如果要想自定义组件 1.那么第一件事就是赋予自定义组件的属性,从效果图上看出,该组件可以存在屏幕的各个角落点,那么位置是其属性之一. 2.既然是卫星菜单,那么主按钮和其附属的小按钮之间的围绕半径也应该作

PHP开发框架Yii Framework教程(10) UI组件 自定义组件

在介绍Yii内置UI组件之前,先介绍一下如何自定义组件,这样也有助于理解CWidget的用法,自定义组件就是重载 CWidget 的init() 和 run() 方法. class MyWidget extends CWidget { public function init() { // 此方法会被 CController::beginWidget() 调用 } public function run() { // 此方法会被 CController::endWidget() 调用 } } 本

自定义组件 UITypeEditor

using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Design; using System.Windows.Forms; using System.Windows.Forms.Design; namespace MyLib { // This UITypeEditor can be associated with Int32, Double and Single // pro

Flex自定义组件开发之日周月日期选择日历控件

原文:Flex自定义组件开发之日周月日期选择日历控件           使用过DateField的我们都知道,DateField 控件是用于显示日期的文本字段,字段右侧带有日历图标.当用户在控件边框内的任一位置单击时,将弹出一个 DateChooser 控件,显示当月的所有日期.如果未选择日期,则该文本字段为空白,并且 DateChooser 控件中将显示当前日期的月份.当 DateChooser 控件处于打开状态时,用户可以在各个月份和年份之间滚动,并选择某个日期.选择日期后,DateCho

Android 自定义标签 和 自定义组件

1    自定义标签 这是我的模板项目目录     既然想像 android:text  那样使用自己的标签,那么首先得有标签. 在 res/values/ 下我新建了个 mm_tag.xml (切记不可出现大写,只能是 小写字母.数字.下划线) 第一步:    自定义 标签     mm_tag.xml <?xml version="1.0" encoding="utf-8"?>   <resources>       <declar

【REACT NATIVE 系列教程之二】创建自定义组件&amp;&amp;导入与使用示例

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/react-native/2219.html 在上一篇  [REACT NATIVE 系列教程之一]触摸事件的两种形式与四种TOUCHABLE组件详解 中的最后介绍了如何使用Touchable的四种组件进行监听触摸事件.  那么紧接着我们利用Touchable来包装一个带图片的Button组件,且设计成可接受很多自定义参数. 一:创建我们自定