扩展的树节点/树视图,几乎就在那里,但是
我正在编写一个扩展的树视图,只是在我的 TreeNode 类中添加了一些额外的属性并提供设计时支持。
代码已经准备就绪,但目前我完全被下面的代码困住了。 我在这一点上尝试的一切都会导致(另一个)异常......
也许有人知道如何进一步发展?我不再知道
using System; using System.ComponentModel; using System.ComponentModel.Design; using System.ComponentModel.Design.Serialization; using System.Drawing.Design; using System.Globalization; using System.Reflection; using System.Runtime.Serialization; using System.Windows.Forms;命名空间 MyProject.Forms { 公共类 MenuTreeView : TreeView { 公共菜单树视图() { // }
[Editor(typeof(MenuTreeNodeCollectionEditor), typeof(UITypeEditor))] //[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public new TreeNodeCollection Nodes { get { return base.Nodes; } } } [Serializable] [DefaultProperty("Text")] [TypeConverter(typeof(MenuTreeNodeConverter))] public class MenuTreeNode : TreeNode, ISerializable { private string description = ""; public MenuTreeNode() : base() { // } public MenuTreeNode(string text) : base(text) { // } public MenuTreeNode(string text, string description) : base(text) { this.description = description; } public MenuTreeNode(string text, MenuTreeNode[] children) : base(text, children) { // } public override object Clone() { object clone = base.Clone(); MenuTreeNode node = clone as MenuTreeNode; if (node != null) { node.Description = Description; return node; } else return clone; } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { Serialize(info, context); } protected override void Deserialize(SerializationInfo info, StreamingContext context) { Description = info.GetString("Description"); base.Deserialize(info, context); } protected override void Serialize(SerializationInfo info, StreamingContext context) { info.AddValue("Description", Description); base.Serialize(info, context); } [DefaultValue("")] public string Description { get { return description; } set { description = value; } } } public class MenuTreeNodeConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type type) { if (type == typeof(string)) { return true; } return base.CanConvertFrom(context, type); } public override bool CanConvertTo(ITypeDescriptorContext context, Type type) { if (type == typeof(InstanceDescriptor) || type == typeof(string)) { return true; } return base.CanConvertTo(context, type); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo info, object value) { if (value != null && value is string) { string[] items = ((string)value).Split(','); return new MenuTreeNode(items[0], items[1]); } return base.ConvertFrom(context, info, value); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo info, object value, Type type) { MenuTreeNode node = value as MenuTreeNode; if (value != null) { if (type == typeof(string)) { return node.Text + "," + node.Description; } else if (type == typeof(InstanceDescriptor)) { ConstructorInfo constructor = typeof(MenuTreeNode).GetConstructor(new Type[] { typeof(string), typeof(string) }); return new InstanceDescriptor(constructor, new object[] { node.Text, node.Description }, true); } } return base.ConvertTo(context, info, value, type); } } public class MenuTreeNodeCollectionEditor : CollectionEditor { public MenuTreeNodeCollectionEditor(Type t) : base(t) { // } protected override Type CreateCollectionItemType() { return typeof(MenuTreeNode); } protected override Type[] CreateNewItemTypes() { return new Type[] { typeof(MenuTreeNode) }; } protected override object CreateInstance(Type itemType) { if (itemType == typeof(MenuTreeNode)) { return new MenuTreeNode(); } return base.CreateInstance(itemType); } protected override string GetDisplayText(object value) { MenuTreeNode node = value as MenuTreeNode; if (node != null) { return "MenuTreeNode: " + node.Text; } return base.GetDisplayText(value); } }
}
[编辑] 将树视图移动到另一个项目后,一切顺利。不要问我为什么...
但是:只保存属性文本和描述,因为设计器不会为每个添加的节点创建局部变量。我怎样才能实现这个目标?
[编辑] 终于,我成功了!感谢这个: http://netcode.ru/ dotnet/?lang=&katID=30&skatID=283&artID=7827
解决方案是从TypeConvertor中去掉typeof(string),当类型为InstanceDescriptor时,只返回默认构造函数。
I am writing an extended treeview, just with a few extra properties in my TreeNode class with designtime support.
The code is allmost ready, but at the moment I'm completely stuck with the following code.
Everything I try at this point results in (another) exception...
Maybe anyone has an idea how to go futher? I don't know it anymore
using System; using System.ComponentModel; using System.ComponentModel.Design; using System.ComponentModel.Design.Serialization; using System.Drawing.Design; using System.Globalization; using System.Reflection; using System.Runtime.Serialization; using System.Windows.Forms;
namespace MyProject.Forms { public class MenuTreeView : TreeView { public MenuTreeView() { // }
[Editor(typeof(MenuTreeNodeCollectionEditor), typeof(UITypeEditor))] //[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public new TreeNodeCollection Nodes { get { return base.Nodes; } } } [Serializable] [DefaultProperty("Text")] [TypeConverter(typeof(MenuTreeNodeConverter))] public class MenuTreeNode : TreeNode, ISerializable { private string description = ""; public MenuTreeNode() : base() { // } public MenuTreeNode(string text) : base(text) { // } public MenuTreeNode(string text, string description) : base(text) { this.description = description; } public MenuTreeNode(string text, MenuTreeNode[] children) : base(text, children) { // } public override object Clone() { object clone = base.Clone(); MenuTreeNode node = clone as MenuTreeNode; if (node != null) { node.Description = Description; return node; } else return clone; } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { Serialize(info, context); } protected override void Deserialize(SerializationInfo info, StreamingContext context) { Description = info.GetString("Description"); base.Deserialize(info, context); } protected override void Serialize(SerializationInfo info, StreamingContext context) { info.AddValue("Description", Description); base.Serialize(info, context); } [DefaultValue("")] public string Description { get { return description; } set { description = value; } } } public class MenuTreeNodeConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type type) { if (type == typeof(string)) { return true; } return base.CanConvertFrom(context, type); } public override bool CanConvertTo(ITypeDescriptorContext context, Type type) { if (type == typeof(InstanceDescriptor) || type == typeof(string)) { return true; } return base.CanConvertTo(context, type); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo info, object value) { if (value != null && value is string) { string[] items = ((string)value).Split(','); return new MenuTreeNode(items[0], items[1]); } return base.ConvertFrom(context, info, value); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo info, object value, Type type) { MenuTreeNode node = value as MenuTreeNode; if (value != null) { if (type == typeof(string)) { return node.Text + "," + node.Description; } else if (type == typeof(InstanceDescriptor)) { ConstructorInfo constructor = typeof(MenuTreeNode).GetConstructor(new Type[] { typeof(string), typeof(string) }); return new InstanceDescriptor(constructor, new object[] { node.Text, node.Description }, true); } } return base.ConvertTo(context, info, value, type); } } public class MenuTreeNodeCollectionEditor : CollectionEditor { public MenuTreeNodeCollectionEditor(Type t) : base(t) { // } protected override Type CreateCollectionItemType() { return typeof(MenuTreeNode); } protected override Type[] CreateNewItemTypes() { return new Type[] { typeof(MenuTreeNode) }; } protected override object CreateInstance(Type itemType) { if (itemType == typeof(MenuTreeNode)) { return new MenuTreeNode(); } return base.CreateInstance(itemType); } protected override string GetDisplayText(object value) { MenuTreeNode node = value as MenuTreeNode; if (node != null) { return "MenuTreeNode: " + node.Text; } return base.GetDisplayText(value); } }
}
[edit]
After moving the Treeview to another project, all goes fine. Don't ask me why...
But: only the properties Text and Description are saved, because the designer does not create local variables for each added node. How can I achieve this?
[edit]
Finally, I got it to work! thanks to this: http://netcode.ru/dotnet/?lang=&katID=30&skatID=283&artID=7827
The solution was to remove the typeof(string) from the TypeConvertor, and when the type is InstanceDescriptor, just return the default constructor.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
终于,我成功了!感谢这篇文章: http://netcode.ru /dotnet/?lang=&katID=30&skatID=283&artID=7827
解决方案是从 TypeConvertor 中删除 typeof(string),当类型为 InstanceDescriptor 时,只需返回默认构造函数即可工作。
Finally, I got it to work! thanks to this article: http://netcode.ru/dotnet/?lang=&katID=30&skatID=283&artID=7827
The solution was to remove the typeof(string) from the TypeConvertor, and when the type is InstanceDescriptor, just returning the default constructor does the job.