我有一个 TreeNode 类派生自 TreeNode ,一个派生自 TreeView 的 TreeView 类,自定义树节点集合。当我尝试通过代码添加节点时,节点会被正确添加和显示,但是当我尝试通过设计器集合编辑器添加节点时,desiger会生成代码,但它不会立即显示更改。我必须构建项目才能显示它们,但节点计数器正在重置。我显然希望它在集合编辑器中单击“确定”按钮时显示更改。
此外,当它遇到BtnOK_click
事件时,它会执行将base.Items = array;
值设置为base.EditValue
的行array
,然后触发OnEditValueChanged()
。但是,在BtnOK_click
事件中,base.EditValue
的值会发生变化,当它达到OnEditValueChanged()
时,由于某种原因,base.EditValue
的值为空。
当我尝试执行像base.EditValue = array;
这样的行时,它会抛出异常:对象引用未设置为对象的实例
以下是相关的集合编辑器方法:
//This is the event which triggers when the user presses the OK button in the collection editor
private void BtnOK_click(object sender, EventArgs e) {
object[] array = new object[this.treeView1.Nodes.Count];
for (int i = 0; i < array.Length; i++)
array[i] = this.treeView1.Nodes[i].Clone();
base.Items = array;
this.treeView1.Dispose();
this.treeView1 = null;
}
protected override void OnEditValueChanged() {
if (base.EditValue != null) {
object[] items = base.Items;
this.propertyGrid1.Site = new PropertyGridSite(base.Context, this.propertyGrid1);
MyTreeNode[] array = new MyTreeNode[items.Length];
for (int i = 0; i < items.Length; i++)
array[i] = (MyTreeNode)((MyTreeNode)items[i]).Clone();
this.treeView1.Nodes.Clear();
this.treeView1.Nodes.AddRange(array);
this.curNode = null;
this.btnAddChild.Enabled = false;
this.btnDelete.Enabled = false;
MyTreeView treeView = this.TreeView;
if (treeView != null)
this.SetImageProps(treeView);
if (items.Length > 0 && array[0] != null)
this.treeView1.SelectedNode = array[0];
}
}
这是 TreeNode 类克隆方法及其相关方法和类(我不知道是否会导致问题,因为此方法似乎工作正常) :
private const string si_children = "children";
private const string si_propBag = "PropBag";
public override object Clone() {
MyTreeNode node;
SerializationInfo si;
SerializationInfo siDemo = new SerializationInfo(typeof(MyTreeNode), new MyTreeNodeFormatterConverter());
StreamingContext sc = new StreamingContext();
bool hasPropBag = false;
this.Serialize(siDemo, sc);
try {
siDemo.GetValue(si_propBag, typeof(OwnerDrawPropertyBag));
hasPropBag = true;
}
catch {
}
if (this._nodes.Count > 0 || hasPropBag) {
si = new SerializationInfo(typeof(MyTreeNode), new MyTreeNodeFormatterConverter());
foreach (SerializationEntry se in siDemo) {
if (se.Name.StartsWith(si_children))
si.AddValue(se.Name, ((MyTreeNode)se.Value).Clone(), typeof(MyTreeNode));
else if (se.Name == si_propBag)
si.AddValue(se.Name, OwnerDrawPropertyBag.Copy((OwnerDrawPropertyBag)se.Value), typeof(OwnerDrawPropertyBag));
else
si.AddValue(se.Name, se.Value, se.ObjectType);
}
node = new MyTreeNode(si, sc);
}
else
node = new MyTreeNode(siDemo, sc);
return node;
}
private class MyTreeNodeFormatterConverter : FormatterConverter {
public MyTreeNodeFormatterConverter()
: base() {
}
public new object Convert(object value, Type type) {
Type value_type;
if (value == null)
throw new ArgumentNullException("value");
value_type = value.GetType();
//Since I'm only adding nodes of type MyTreeNode, TreeNode nodes can be safely cast back to their original type MyTreeNode
if (value_type == typeof(MyTreeNode) || value_type == typeof(TreeNode))
return value as MyTreeNode;
else if (value_type == typeof(OwnerDrawPropertyBag))
return value as OwnerDrawPropertyBag;
else
return base.Convert(value, type);
}
}
protected MyTreeNode(SerializationInfo si, StreamingContext sc)
: base(si, sc) {
}
protected override void Deserialize(SerializationInfo si, StreamingContext sc) {
MyTreeNode[] children;
int base_nodes_count;
base.Deserialize(si, sc);
base_nodes_count = base.Nodes.Count;
this.Init();
if (base_nodes_count > 0) {
children = new MyTreeNode[base_nodes_count];
for (int i = 0; i < base_nodes_count; i++)
children[i] = (MyTreeNode)si.GetValue(si_children + i, typeof(MyTreeNode));
this._nodes.AddRangeBase(children);
}
}
private void Init() {
this._nodes = new MyTreeNodeCollection(this, base.Nodes);
}
答案 0 :(得分:0)
我通过在TreeViewDesginer中添加以下行来显示添加的节点:
MyTreeNodeCollectionEditor.MyTreeNodeCollectionEditor uITypeEditor = this._targetProperty.GetEditor(typeof(UITypeEditor)) as MyTreeNodeCollectionEditor.MyTreeNodeCollectionEditor;
MyTree.MyTreeView treeView = (MyTree.MyTreeView)this._designer.Component;
treeView.Nodes.Clear();
treeView.Nodes.AddRange(uITypeEditor.nodes);