c#

位置:IT落伍者 >> c# >> 浏览文章

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


发布日期:2018年04月22日
 
编写与.NET属性窗口交互的RAD组件(三)

编写和显示订制的类型

属性窗口中的编辑有如下三种工作方式有些场合可以作为字符串来编辑然后由TypeConverter来实现类型的转换可以显示一个下拉列表来选择值一个省略按钮提供其他的UI界面来编辑值比如FileDialog和FontPicker我们已经讲过了字符串形式接着我们就来看下拉列表

NET framework已经包含了好几种下拉列表的例子如ColorAccessibleRoleDock等属性我们从下图可以看到下拉列表的具体实现

下拉列表编辑器

实现下拉的工作同样是由TypeConverter来定义如果看TypeConverter的说明可以看到有三个虚函数来实现这个功能GetStandardValuesSupported()GetStandardValues()和GetStandardValuesExclusive()重载这些方法我们可以为属性提供预先定义好的值列表实际上是TypeConverter实现了下拉列表中的枚举值属性窗口自己本身并没有代码来处理这种下拉列表的编辑而仅仅是使用TypeConverter的方法

举个例来说我们有一个包含Relation属性的FamilyMember组件允许用户选择与其他人之间的关系如果要使设计时界面更友好的话属性窗口应该使用下拉列表来提供一些常用值的选择如motherfatherdaughter和sister等除了提供的常用值之外组件使用者也可以输入其他的表示关系的字符串值

public class FamilyMember : Component

{

private string relation = Unknown;

[TypeConverter(typeof(RelationConverter))Category(Details)]

public string Relation

{

get { return relation;}

set { thisrelation = value;}

}

}

internal class RelationConverter : StringConverter

{

private static StandardValuesCollection defaultRelations =

new StandardValuesCollection(

new string[]{Mother Father Sister

Brother Daughter Son

Aunt Uncle Cousin});

public override bool GetStandardValuesSupported(

ITypeDescriptorContext context)

{

return true;

}

public override bool GetStandardValuesExclusive(

ITypeDescriptorContext context)

{

// returning false here means the property will

// have a drop down and a value that can be manually

// entered

return false;

}

public override StandardValuesCollection GetStandardValues(

ITypeDescriptorContext context)

{

return defaultRelations;

}

}

不过如何做一个更加定制化的UI呢?我们可以使用UITypeEditor类UITypeEditor类包括了在显示属性或者是编辑属性(比如下拉列表和省略按钮)时可以由属性窗口调用的方法

一些类似于ImageColorFontName的属性类型会在属性值的左边有一个小的图形化表示这是通过重载UITypeEditor的PaintValue方法实现的当属性窗口得到定义了编辑器的属性值的时候它就提供给编辑器一个矩形框对象(Rectangle)和画图的对象(Graphic)他们都包含在PaintValue方法的事件参数PaintValueEventArgs中举个例子来说我们有一个Grade类需要有图形化的表示下面就是我们的Grade类

[Editor(typeof(GradeEditor) typeof(SystemDrawingDesignUITypeEditor))]

[TypeConverter(typeof(GradeConverter))]

public struct Grade

{

private int grade;

public Grade(int grade)

{

thisgrade = grade;

}

public int Value

{

get

{

return grade;

}

}

}

当我们输入一个年龄的时候我们可以看到左边的一个图形表示

输入年龄

实现它并不困难注意到赋给Grade类的EditorAttribute特性它就是下面的这个类

public class GradeEditor : UITypeEditor

{

public override bool GetPaintValueSupported(

ITypeDescriptorContext context)

{

// let the property browser know wed like

// to do custom painting

return true;

}

public override void PaintValue(PaintValueEventArgs pe)

{

// choose the right bitmap based on the value

string bmpName = null;

Grade g = (Grade)peValue;

if (gValue > )

{

bmpName = bestbmp;

}

else if (gValue > )

{

bmpName = okbmp;

}

else

{

bmpName = badbmp;

}

// draw that bitmap onto the surface provided

Bitmap b = new Bitmap(typeof(GradeEditor) bmpName);

peGraphicsDrawImage(b peBounds);

bDispose();

}

}

像我们上面提到的UITypeEditor可以实现属性的下拉选择和弹出对话框选择后面的例子会包括这样的代码如果想知道进一步的信息的话就要参考UITypeEditorGetEditStyle和UITypeEditorEditValue方法以及IWindowsFormsEditorService接口               

上一篇:.Net 标签(Attribute) 背景介绍

下一篇:C#创建Windows服务