C#.Net组件开发 - 设计时使用自定义属性编辑器持久化对象
C#.Net组件开发 - 设计时使用自定义属性编辑器持久化对象
如题,前几天写了篇C#.Net开发继承UITypeEditor接口的自定义属性编辑器 ,总觉得不完美,这个控件是用带特殊分隔符的字符串持久化对象,可以打开xx.Designer.cs文件查看Items属性,虽然实现了所要的功能,但走的不是正道,其实有更专业的做法,设计时可以参考ListBox.Items对象的持久化后的代码。人类对探索总是充满好奇心,揣到一副不到黄河心不死的心理,花了一天时间找资料动手研究终于修出正果。
(本示例基于开发自定义Component组件详细讲解)
ComponentCS组件,继承Component。
自定义的属性编辑器,派生UITypeEditor基类。
frmTester.Designer.cs文件,ComponentCS1组件设计时生成的代码。
按F5运行程序,程序自动加载持久化的数据,如下图:
测试用的对象,请观察frmTester.Designer.cs文件中该对象的持久化属性的源码。
自定义组件:
自定义的属性编辑器:
自定义设计器:
C/S框架网原创作品,如转载请注明出处:www.csframework.com
Source Code:
扫一扫加作者微信
如题,前几天写了篇C#.Net开发继承UITypeEditor接口的自定义属性编辑器 ,总觉得不完美,这个控件是用带特殊分隔符的字符串持久化对象,可以打开xx.Designer.cs文件查看Items属性,虽然实现了所要的功能,但走的不是正道,其实有更专业的做法,设计时可以参考ListBox.Items对象的持久化后的代码。人类对探索总是充满好奇心,揣到一副不到黄河心不死的心理,花了一天时间找资料动手研究终于修出正果。
(本示例基于开发自定义Component组件详细讲解)
ComponentCS组件,继承Component。
自定义的属性编辑器,派生UITypeEditor基类。
frmTester.Designer.cs文件,ComponentCS1组件设计时生成的代码。
按F5运行程序,程序自动加载持久化的数据,如下图:
测试用的对象,请观察frmTester.Designer.cs文件中该对象的持久化属性的源码。
C# Code:
/// <summary>
/// 测试用的对象。
/// 请观察xxx.Designer.cs文件中该对象的属性持久化。
/// 必须定义[Serializable]属性。
/// </summary>
[Serializable]
public class MyObject
{
private int _Age = 0;
private string _Item = "";
private string[] _MyFavorite;
private MyEnumType _EnumType;
private Point _Location;
private DateTime? _BirthDay;
private ArrayList _Objects;
public MyObject()
{
_Objects = new ArrayList();
}
/// <summary>
/// 持久化嵌套的对象数组,.Net设计器将对象持久化到res文件中
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Localizable(true)]
public ArrayList Objects
{
get { return _Objects; }
set { _Objects = value; }
}
//枚举类型
public MyEnumType EnumType
{
get { return _EnumType; }
set { _EnumType = value; }
}
public Point Location
{
get
{
return _Location;
}
set
{
_Location = value;
}
}
public int Age
{
get { return _Age; }
set { _Age = value; }
}
/// <summary>
/// 定义可空类型
/// </summary>
public DateTime? BirthDay
{
get { return _BirthDay; }
set { _BirthDay = value; }
}
public string Item
{
get { return _Item; }
set { _Item = value; }
}
public override string ToString()
{
//用于在Properties Window内显示的名称
return "(MyObject)";
}
/// <summary>
/// 测试持久化字符串数组
/// </summary>
public string[] MyFavorite
{
get { return _MyFavorite; }
set { _MyFavorite = value; }
}
}
//来源:C/S框架网(www.csframework.com) QQ:1980854898
/// <summary>
/// 测试用的对象。
/// 请观察xxx.Designer.cs文件中该对象的属性持久化。
/// 必须定义[Serializable]属性。
/// </summary>
[Serializable]
public class MyObject
{
private int _Age = 0;
private string _Item = "";
private string[] _MyFavorite;
private MyEnumType _EnumType;
private Point _Location;
private DateTime? _BirthDay;
private ArrayList _Objects;
public MyObject()
{
_Objects = new ArrayList();
}
/// <summary>
/// 持久化嵌套的对象数组,.Net设计器将对象持久化到res文件中
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Localizable(true)]
public ArrayList Objects
{
get { return _Objects; }
set { _Objects = value; }
}
//枚举类型
public MyEnumType EnumType
{
get { return _EnumType; }
set { _EnumType = value; }
}
public Point Location
{
get
{
return _Location;
}
set
{
_Location = value;
}
}
public int Age
{
get { return _Age; }
set { _Age = value; }
}
/// <summary>
/// 定义可空类型
/// </summary>
public DateTime? BirthDay
{
get { return _BirthDay; }
set { _BirthDay = value; }
}
public string Item
{
get { return _Item; }
set { _Item = value; }
}
public override string ToString()
{
//用于在Properties Window内显示的名称
return "(MyObject)";
}
/// <summary>
/// 测试持久化字符串数组
/// </summary>
public string[] MyFavorite
{
get { return _MyFavorite; }
set { _MyFavorite = value; }
}
}
//来源:C/S框架网(www.csframework.com) QQ:1980854898
自定义组件:
C# Code:
[Designer(typeof(MyComponentDesigner), typeof(IDesigner))]
[DefaultProperty("Object")]
public partial class ComponentCS : Component
{
/// <summary>
/// 嵌套的对象,打开属性编辑器可修改这个对象
/// </summary>
private MyObject _Object = new MyObject();
public ComponentCS(IContainer container)
: base()
{
container.Add(this);
}
/// <summary>
/// 嵌套的对象,打开属性编辑器可修改这个对象
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Editor(typeof(MyItemEditor), typeof(UITypeEditor))]
[LocalizableAttribute(true)]
[Category("Appearance")]
[Description("MyObject类型对象")]
public MyObject Object
{
get { return _Object; }
set { _Object = value; }
}
}
//来源:C/S框架网(www.csframework.com) QQ:1980854898
[Designer(typeof(MyComponentDesigner), typeof(IDesigner))]
[DefaultProperty("Object")]
public partial class ComponentCS : Component
{
/// <summary>
/// 嵌套的对象,打开属性编辑器可修改这个对象
/// </summary>
private MyObject _Object = new MyObject();
public ComponentCS(IContainer container)
: base()
{
container.Add(this);
}
/// <summary>
/// 嵌套的对象,打开属性编辑器可修改这个对象
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Editor(typeof(MyItemEditor), typeof(UITypeEditor))]
[LocalizableAttribute(true)]
[Category("Appearance")]
[Description("MyObject类型对象")]
public MyObject Object
{
get { return _Object; }
set { _Object = value; }
}
}
//来源:C/S框架网(www.csframework.com) QQ:1980854898
自定义的属性编辑器:
C# Code:
/// <summary>
///自定义的属性编辑器
/// </summary>
public class MyItemEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (provider != null)
{
IWindowsFormsEditorService svc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (svc != null && context.Instance != null)
{
//取出设计器所在的窗体(组件/控件所在窗体)
IDesignerHost host = (IDesignerHost)provider.GetService(typeof(IDesignerHost));
if (host == null) return value;
//context.Instance:可以得到当前的Component1组件。
ComponentCS c = context.Instance as ComponentCS;
MyObject o = c.Object;
if (o == null) o = new MyObject();
frmMyObjectEditor editForm = new frmMyObjectEditor(o);
svc.ShowDialog(editForm);//打开属性编辑窗体
editForm.Dispose();//释放内存
//重新序列化内容到.Designer.cs文件
context.PropertyDescriptor.SetValue(context.Instance, value);
return o;//返回修改后的对象
}
}
return value; //返回预设的对象
}
}
//来源:C/S框架网(www.csframework.com) QQ:1980854898
/// <summary>
///自定义的属性编辑器
/// </summary>
public class MyItemEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (provider != null)
{
IWindowsFormsEditorService svc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (svc != null && context.Instance != null)
{
//取出设计器所在的窗体(组件/控件所在窗体)
IDesignerHost host = (IDesignerHost)provider.GetService(typeof(IDesignerHost));
if (host == null) return value;
//context.Instance:可以得到当前的Component1组件。
ComponentCS c = context.Instance as ComponentCS;
MyObject o = c.Object;
if (o == null) o = new MyObject();
frmMyObjectEditor editForm = new frmMyObjectEditor(o);
svc.ShowDialog(editForm);//打开属性编辑窗体
editForm.Dispose();//释放内存
//重新序列化内容到.Designer.cs文件
context.PropertyDescriptor.SetValue(context.Instance, value);
return o;//返回修改后的对象
}
}
return value; //返回预设的对象
}
}
//来源:C/S框架网(www.csframework.com) QQ:1980854898
自定义设计器:
C# Code:
/// <summary>
/// 自定义设计器
/// </summary>
public class MyComponentDesigner : ComponentDesigner
{
public MyComponentDesigner()
: base()
{
// 添加"编辑Items"到右键菜单和智能标记中。
DesignerVerb verb = new DesignerVerb("编辑Items", new EventHandler(OnDesignItems));
this.Verbs.Add(verb);
}
private void OnDesignItems(object sender, EventArgs e)
{
this.DoDefaultAction();
}
// 1、可以设计Component的默认事件创建方法签名,并将用户的光标定位到该位置。
// 2、也可以为Component添加双击时要进行的操作。
public override void DoDefaultAction()
{
ComponentCS c = this.Component as ComponentCS;
if (c.Object == null) c.Object = new MyObject();
frmMyObjectEditor editor = new frmMyObjectEditor(c.Object);
//调用属性编辑窗体编辑对象
if (DialogResult.OK == editor.ShowDialog())
{
//取出Object属性的PropertyDescriptor,派生类:ReflectPropertyDescriptor
//PropertyDescriptor:是抽象基类.
PropertyDescriptor pd = TypeDescriptor.GetProperties(c)["Object"];
//当设计器修改了对象的属性,持久化属性的值到Designer.cs文件。
if (pd != null) pd.SetValue(c, c.Object);
}
editor.Dispose();
}
}
//来源:C/S框架网(www.csframework.com) QQ:1980854898
/// <summary>
/// 自定义设计器
/// </summary>
public class MyComponentDesigner : ComponentDesigner
{
public MyComponentDesigner()
: base()
{
// 添加"编辑Items"到右键菜单和智能标记中。
DesignerVerb verb = new DesignerVerb("编辑Items", new EventHandler(OnDesignItems));
this.Verbs.Add(verb);
}
private void OnDesignItems(object sender, EventArgs e)
{
this.DoDefaultAction();
}
// 1、可以设计Component的默认事件创建方法签名,并将用户的光标定位到该位置。
// 2、也可以为Component添加双击时要进行的操作。
public override void DoDefaultAction()
{
ComponentCS c = this.Component as ComponentCS;
if (c.Object == null) c.Object = new MyObject();
frmMyObjectEditor editor = new frmMyObjectEditor(c.Object);
//调用属性编辑窗体编辑对象
if (DialogResult.OK == editor.ShowDialog())
{
//取出Object属性的PropertyDescriptor,派生类:ReflectPropertyDescriptor
//PropertyDescriptor:是抽象基类.
PropertyDescriptor pd = TypeDescriptor.GetProperties(c)["Object"];
//当设计器修改了对象的属性,持久化属性的值到Designer.cs文件。
if (pd != null) pd.SetValue(c, c.Object);
}
editor.Dispose();
}
}
//来源:C/S框架网(www.csframework.com) QQ:1980854898
C/S框架网原创作品,如转载请注明出处:www.csframework.com
Source Code:
扫一扫加作者微信
版权声明:本文为开发框架文库发布内容,转载请附上原文出处连接
NewDoc C/S框架网