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# 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 自定义组件: 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 自定义的属性编辑器: 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 自定义设计器: 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 C/S框架网原创作品,如转载请注明出处:www.csframework.com Source Code: 扫一扫加作者微信
参考文档:
C#.Net自定义控件 - GridPopupContainerEdit C#.Net自定义控件 - GridPopupContainerLookup C#.Net开发继承UITypeEditor接口的自定义属性编辑器 标签:C#.Net组件开发 - 设计时持久化对象数组 标签:C#.Net组件开发 - 属性窗体内显示自定义名称 标签:C#.Net组件开发 - 自定义设计器(ComponentDesigner) 标签:C#.Net组件开发 - 自定义设计器持久化对象的属性 标签:C#.Net组件开发 - 自定义属性编辑器持久化对象的属性 您的开发框架使用自定义表单技术吗? C#.Net组件开发(高级篇) - 设计时在窗体设计器文件内生成组件的代码 C#.Net组件开发(高级篇) - 自定义CollectionEditor编辑器 C#.Net组件开发(高级篇) - 开发复杂的设计时组件编辑器 C#.Net组件开发(高级篇) - 全部源码下载 C#.Net组件开发 - 使用Attach to Process实时调试设计器代码 C#.Net组件开发(高级篇) - 使用自定义TypeConverter生成设计时代码
其它资料:
什么是C/S结构? | C/S框架核心组成部分 | C/S框架-WebService部署图 | C/S框架-权限管理 | C/S结构系统框架 - 5.1旗舰版介绍 | C/S结构系统框架 - 功能介绍 | C/S结构系统框架 - 产品列表 | C/S结构系统框架 - 应用展示(图) | 三层体系架构详解 | C/S架构轻量级快速开发框架 | C/S框架网客户案例 | WebApi快速开发框架 | C/S框架代码生成器 | 用户授权注册软件系统 | 版本自动升级软件 | 数据库底层应用框架 | CSFramework.CMS内容管理系统 | |