C # TreeView SelectedNode является нулевым? - PullRequest
1 голос
/ 09 февраля 2012

У меня есть два метода, напрямую работающих с моим TreeView (tvTreeview - оригинальное имя, а?):

private void tvTreeView_MouseClick(object sender, MouseEventargs e)
{
  selectedNode = tvtreeView.HitTest(e.Location).Node;
  /* some logic */
}

и

private void cbValue_Changed(object sender, EvenArgs e)
{
  /* some logic related to changing the value that the node refers to.
   * The nodes in the TreeView are each attached to a different bool,
   * find that bool and check the value in memory matches that of the
   * dropdown combobox */
  /* clear the tree */
  tvTreeView.BeginUpdate();
  tvTreeView.Nodes.Clear();

  //re-populate and re-draw the TreeView, then call the EndUpdate method

  tvtreeView.EndUpdate();
  tvTreeView.SelectedNode = selectedNode;
  tvTreeView.SelectedNode.Expand();
}

По сути, я перерисовываю TreeView при изменении значения выпадающего списка. Переменная selectedNode определяется в верхней части класса:

public static TreeNode selectedNode;

Я получаю исключение NullReferenceException, брошенное в tvTreeView.SelectedNode, Expand (); только когда выбранный узел НЕ является дочерним узлом (т. е. когда он является родительским или корневым). Например, если мой TreeView выглядит так:

Root <- no NullReferenceException thrown
 -Parent <- no NullReferenceException thrown
   -Child <- NullReferenceException thrown
   -Child <- NullReferenceException thrown
 -Parent <- no NullReferenceException thrown
   -Child <- NullReferenceException thrown

Исключение NullReferenceException создается на любом из дочерних узлов, но не на родительских или корневых узлах.

Когда я ставлю точку останова (или когда генерируется исключение), Visual Studio сообщает мне, что selectedNode не равен NULL, но tvTreeView.SelectedNode - это; что странно, особенно из-за строки:

tvTreeView.Selectednode = selectedNode();
//tvTreeView.selectedNode is Null
//selectedNode is not null

Когда я перерисовываю TreeView, он содержит те же данные (загружаются обратно из памяти), что и при первом рисовании, и узлы добавляются в том же порядке.

Я просто неправильно подхожу к этому? Почему tvtreeView.SelectedNode только null, когда я выбираю дочерний узел, а не родительский / корневой узел?

Я знаю, что когда вы очищаете TreeView, ни один из узлов больше не существует, поэтому я предполагаю, что моя проблема связана с этим, но почему исключение выдается только тогда, когда пользователь нажимает на дочерний узел?

1 Ответ

2 голосов
/ 10 февраля 2016

tvTreeView.Selectednode остается нулевым, потому что вы очистили дерево. У меня была похожая проблема, даже когда я пытался выбрать элемент дерева.

Не рекомендуется, но решает проблему - вместо очистки дерева вы можете создать новое.

 trv = new System.Windows.Forms.TreeView();
 /*build the tree*/
 trv.SelectedNode = elementOfTheTree;

Второй вариант - использовать обработчик события beforeSelect и принудительно выполнить действие выбора. SelectedNode хорошо реагирует на эти обработчики событий. Возможно, что-то вроде этого:

bool isBeforeSelectInProgress = false;
private void beforeSelectFromTrv(object sender, TreeViewCancelEventArgs e)
{
    if (isBeforeSelectInProgress)
    {
        e.Cancel = true;
        return;
    }

    isBeforeSelectInProgress = true;

    try
    {
        //save the changes and return the node that need to be focus 
        TreeNode nodeToSelect = saveChanges((TreeNode)e.Node);
        //cancel any other selection event
        e.Cancel = true;
        nodeToSelect.EnsureVisible();
        //release the event handler
        isBeforeSelectInProgress = false;
        //and than select the node you wish will be selected
        (sender as System.Windows.Forms.TreeView).SelectedNode = toSelect;
    }
    finally
    {
        isBeforeSelectInProgress = false;
    }
}
...