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);
Другие вопросы по тегам