C#組件編程(2)

淡淡的烟草味﹌ 2022-08-26 03:47 278阅读 0赞

C#組件編程(2)

較复雜的屬性為了編輯方便,就要用到屬性編輯器.
由于在屬性視窗中只能識別字符串類型,如果是非字符串類型的屬性還需要用到類型轉換器.
下面就分別講它們的使用方法:

1.屬性編輯器Property Editor
在vs环境中Property Editor有两种,一种是vs自带的,一种是Component编写者根据自己需求而重新编写的。

示例:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace Components
{
// 这个例子用到了vs 2005里的List<>.
public class Demo3 : Component
{
public Demo3()
{
_students = new List(); // 一定要在构造函数中实例化_students。
}

private List _students;
private string _grade;

// 使用 vs自带的Editor。
// 如果没有DesignerSerializationVisibilityAttribute的话,对Students设值,值不能被保存。
// 大家可以把DesignerSerializationVisibilityAttribute注释掉,对Students设值后,关闭vs环境,再重新打开项目,观察Students的值没有被保存下来。
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public List Students
{
get { return _students; }
set { _students = value; }
}

//使用用户自定义的Editor。
[Editor(typeof(GradeEditor), typeof(UITypeEditor)), LocalizableAttribute(true)]
public string Grade
{
get { return _grade; }
set { _grade = value; }
}
}

public class Student
{
private int _id;
private string _name;

public int Id
{
get { return _id; }
set { _id = value; }
}

public string Name
{
get { return _name; }
set { _name = value; }
}
}

/*//在vs2003中實現集合的方式,這比在vs2005中使用泛型复雜多了.
public class StudentCollection : CollectionBase,IList
{
public Student this[int index]
{
get { return (Student)(List[index]); }
set { List[index] = value; }
}

public int Add(Student value)
{
return List.Add(value);
}

public int IndexOf(Student value)
{
return List.IndexOf(value);
}

public bool Contains(Student value)
{
return List.Contains(value);
}

public void Remove(Student value)
{
List.Remove(value);
}
} */

public class GradeEditor : UITypeEditor
{
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand)]
public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
// UITypeEditorEditStyle有三种,Modal是弹出式,DropDown是下拉式,None是没有。
return UITypeEditorEditStyle.Modal;
}

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand)]
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)
{
// 得到editor service,可由其创建弹出窗口。
IWindowsFormsEditorService editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

// context.Instance —— 可以得到当前的Demo3对象。
// ((Demo3)context.Instance).Grade —— 可以得到当前Grade的值。

frmGradeEditor dialog = new frmGradeEditor();
editorService.ShowDialog(dialog);
String grade = dialog.Grade;
dialog.Dispose();

return grade;
}
}
}

2.TypeConverterAttribute(类型转换)

示例:
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Globalization;

namespace ClassLibrary1
{
public class Class1 : Component
{
private Size _size;

public Class1()
{
_size = new Size();
}

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[TypeConverter(typeof(SizeConverter))] // —— 注1,也可以把这句TypeConverterAttribute写在注2处。
public Size Size
{
get { return _size; }
set { _size = value; }
}
}

public class SizeConverter : TypeConverter // 我们自定义的Converter必须继承于TypeConverter基类。
{
///


/// 是否能用string转换到Size类型。
///

/// 上下文。
/// 转换源的Type。
///
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{ return true; }
else
{ return false; }
}

///


/// 从string转到Size类型。
///

/// 提供Component的上下文,如Component.Instance对象等。
/// 提供区域信息,如语言、时间格式、货币格式等
///
///
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value == null || value.ToString().Length == 0) return new Size();
char spliter = culture.TextInfo.ListSeparator[0]; // 得到字符串的分隔符
string[] ss = ((string)value).Split(spliter);

Int32Converter intConverter = new Int32Converter(); // 得到类型转换器,.net中为我们定义了一些常见的类型转换器。
return new Size((Int32)intConverter.ConvertFromString(context, culture, ss[0]),
(Int32)intConverter.ConvertFromString(context, culture, ss[1]));
}

/**


/// 是否能用Size转换到string类型。
///

///
/// 转换目标的类型。
///
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(Size)) // 如果是Size格式,则允许转成string。
{ return true; }
else
{ return false; }
}

// 在Property窗口中显示为string类型。
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (value == null) return string.Empty;
if (destinationType == typeof(string))
{
Size size = (Size)value;
TypeConverter intConverter = TypeDescriptor.GetConverter(typeof(Int32)); // 得到类型转换器的另一种方式。
char spliter = culture.TextInfo.ListSeparator[0]; // 得到字符串的分隔符

return string.Join(spliter.ToString(), new string[]{
intConverter.ConvertToString(context, culture, size.Length),
intConverter.ConvertToString(context, culture, size.Width)});
}
return string.Empty;
}

// TypeConverter还有几个虚方法,请大家自己研究。
}

// [TypeConverter(typeof(SizeConverter))] —— 注2
public class Size
{
private Int32 _length;
private Int32 _width;

public Size(Int32 length, Int32 width)
{
_length = length;
_width = width;
}

public Size() : this(0, 0)
{
}

public Int32 Length
{
get { return _length; }
set { _length = value; }
}

public Int32 Width
{
get { return _width; }
set { _width = value; }
}
}
}

发表评论

表情:
评论列表 (有 0 条评论,278人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C#(2)

    C\組件編程(2) 較复雜的屬性為了編輯方便,就要用到屬性編輯器. 由于在屬性視窗中只能識別字符串類型,如果是非字符串類型的屬性還需要用到類型轉換器. 下面就分別講它

    相关 Socket--同步的應用

    同步編程使用的情況不多,在以下3種情況下可以使用同步: 1.客戶端數量較少情況下的服務端編程 2.客戶端數量較多,但都是短連接情況下的服務端編程 3.客戶端編程

    相关 C#中的碼轉化

    C\中的編碼轉化 在轉化之前,必須要先知道當前變量的編碼.對於.NET下的string永远是Unicode的. 對於從文本文件中讀取的byte\[\]或string的編碼,也

    相关 JS規範 積累

    1.命名推薦:userName(第一個單詞首字母小寫,其他首字母大寫) 2.函數名有必要加上前綴fn,比如fnGetName,最好採用動名詞組合,函數的參數要加註釋 3