Custom TreeView не отображает измененные при редактировании узлов через редактор конструктора
У меня есть класс 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);
}
1 ответ
Я получил его для отображения добавленных узлов, добавив в 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);