1
votes

I'm trying to actually deselect all nodes in my TreeView. By "actually", I mean that TreeView1.SelectedNode = null; will actually deselect the node in the tree.

Right now, visually speaking, the node is deselected. However, when I try to add a new node, the treeview will automatically select the first node in the tree (at the top) and create a subnode when ideally I want to create a parent node. I can't just deselect the selected node before adding either, because the user might want to add a child node. The behaviour I'd like is for the parent/child node adding to be based on what is selected in the treeview. If nothing is selected, add a parent, if something is selected, add a child in that selected node.

I construct a TreeNode object called node in a function with images and text and all that then I have the following:

        if (tvContent.SelectedNode == null)
            tvContent.Nodes.Add(node);
        else
        {
            tvContent.SelectedNode.Nodes.Add(node);
            tvContent.SelectedNode.Expand();
        }

I have a "Deselect All" button that is supposed to make the above code work. The code for that button is simply:

tvContent.SelectedNode = null;

Pardon my tagging both C# and VB.NET. I'm good with both so if someone can help me out in either language that'd be terrific!

Thanks

EDIT: Interesting. It seems that while testing if the selected node is null, .NET will automatically set the selected node to the first node in the tree. The following code shows the "trigger" message box, but immediately selects the first node in the tree after the if statement is complete.

    private void btnDeselectAll_Click(object sender, EventArgs e)
    {
        tvContent.SelectedNode = null;
        if (tvContent.SelectedNode == null) MessageBox.Show("trigger");
    }

EDIT2: The issue lies in using an InputBox for the title input of the node. For whatever reason, that changes the selected node of the treeview. I tried this in a stock project and managed to replicate the issue. I guess there's no fixing this :S

3
Put a breakpoint right on tvContent.SelectedNode blocks, F11 (step by step debugging) afterwards to see which line of your code changed the tvContent.SelectedNode to the first node.Martheen
Didn't find any code that changed it, it honestly looks like it's being changed on its own.Dan
@Martheen please check out my post edit. It seems that this is strange behaviour within .netDan
@Martheen Check my post's "EDIT2". Any ideas?Dan
What do you mean by using InputBox for title input? Might as well just post your stock project so we can replicate the issue.Martheen

3 Answers

0
votes

I tried to reproduce your scenario but failed. After setting SelectedNode to null, it remained null for me when trying to read it back. A few things I want to check on:

  1. Are you sure you're actually deselecting the node? If you have the "HideSelection" property of the TreeView set to True (default), the selection disappears anytime the TreeView loses focus (like when you click your deselect all button - making it look like it's working). Make sure this isn't the case by setting HideSelection to False.

  2. Are you sure you're not triggering an event handler (like SelectedNodeChanged) when you set the SelectedNode to null?

0
votes

So it turns out that getting "true" deselection isn't possible. As soon as the treeview loses focus then gains focus again (e.g. via an inputbox window popping up), the selected node will no longer be null.

My work around was to introduce a panel that becomes visible with some input options so that node title input is done on the main form instead of on another form. I don't like this fix but it's all that can be done.

0
votes

This worked for me

Private LastSelectetNode As TreeNode

Protected Overrides Sub OnBeforeSelect(e As TreeViewCancelEventArgs)
    e.Cancel = LastSelectetNode Is Nothing  
    MyBase.OnBeforeSelect(e)
End Sub

Protected Overrides Sub OnMouseUp(e As MouseEventArgs)
    Dim nd = MyBase.HitTest(e.Location).Node
    If LastSelectetNode Is nd Then
        SelectedNode = Nothing
        LastSelectetNode = Nothing
    Else
        LastSelectetNode = nd
    End If
    MyBase.OnMouseUp(e)
End Sub