akinuri
akinuri

Reputation: 12029

Deselect TreeView Node

I do a lot of modifications in Windows so I constantly visit this and that folder. Doing this manually is a pain. That's why I thought about creating a small tool which will contain some of the environment variables.

screenshot of the tool

I have a TreeView. I select a node and the tool opens the corresponding folder.

public static class EnvPaths {
    public static string HomeDrive = Environment.GetEnvironmentVariable("HomeDrive");
    public static string ProgramFiles = Environment.GetEnvironmentVariable("ProgramFiles");
    public static string CommonFiles = Environment.GetEnvironmentVariable("CommonProgramFiles");
    public static string ProgramFilesX86 = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
    public static string CommonFilesX86 = Environment.GetEnvironmentVariable("CommonProgramFiles(x86)");
    public static string ProgramData = Environment.GetEnvironmentVariable("ProgramData");
    public static string User = Environment.GetEnvironmentVariable("HomePath");
    public static string AppData = Environment.GetEnvironmentVariable("AppData");
    public static string QuickLaunch = AppData + @"\Microsoft\Internet Explorer\Quick Launch";
    public static string Temp = Environment.GetEnvironmentVariable("Temp");
    public static string Windows = Environment.GetEnvironmentVariable("WinDir");
    public static string System32 = Windows + @"\system32";
    public static string etc = System32 + @"\drivers\etc";
}

private void WinFoldersTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
    if (WinFoldersTreeView.SelectedNode != null)
    {
        var selectedFolder = WinFoldersTreeView.SelectedNode.Text;
        switch (selectedFolder)
        {
            case "Home Drive":
                Process.Start(EnvPaths.HomeDrive);
                break;
            case "Program Files":
                Process.Start(EnvPaths.ProgramFiles);
                break;
            case "Common Files":
                Process.Start(EnvPaths.CommonFiles);
                break;
            case "Program Files (x86)":
                Process.Start(EnvPaths.ProgramFilesX86);
                break;
            case "Common Files (x86)":
                Process.Start(EnvPaths.CommonFilesX86);
                break;
            case "ProgramData":
                Process.Start(EnvPaths.ProgramData);
                break;
            case "User":
                Process.Start(EnvPaths.User);
                break;
            case "AppData":
                Process.Start(EnvPaths.AppData);
                break;
            case "Quick Launch":
                Process.Start(EnvPaths.QuickLaunch);
                break;
            case "Temp":
                Process.Start(EnvPaths.Temp);
                break;
            case "Windows":
                Process.Start(EnvPaths.Windows);
                break;
            case "System32":
                Process.Start(EnvPaths.System32);
                break;
            case "etc":
                Process.Start(EnvPaths.etc);
                break;
        }
    }
}

I have a problem though. Once it opens the folder, I want to deselect the selected node. So if I open a folder, close it, and want to open it again, I can't. I can't select the selected node again. I need to select another node, and then select the original node again. Which will open two folders, not one.

I've used WinFoldersTreeView.SelectedNode = null to deselect the node. This works but causes another problem. Since the TreeView has its AfterSelect event attached, setting WinFoldersTreeView.SelectedNode to null triggers the AfterSelect event again. I end up opening two folders.

How can I deselect the selected node without triggering the AfterSelect event?

Upvotes: 2

Views: 1789

Answers (2)

Craig
Craig

Reputation: 11

You can catch the Select event and cancel it. You'll obviously want to put some conditional logic in to decide when you want to block it and when you don't, but I've tested the code below and it works.

If you don't suspend the layout during the cancel action then on the screen the node text appears to be selected (Blue background color) for a fraction of a second and then instantly goes back to being unselected (no background color). Just an annoyance really.

private void myTreeView_BeforeSelect(object sender, TreeViewCancelEventArgs e)
{
    treeViewReallocateTo.SuspendLayout();
    e.Cancel = true;
    treeViewReallocateTo.ResumeLayout();
}

Upvotes: 1

LarsTech
LarsTech

Reputation: 81610

I think the NodeMouseClick will do what you want, which means you don't have to de-select anything:

void WinFoldersTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) {
  switch (e.Node.Text) {
    case "Home Drive":
      Process.Start(EnvPaths.HomeDrive);
      break;
    case "Program Files":
      Process.Start(EnvPaths.ProgramFiles);
      break;
    case "Common Files":
      Process.Start(EnvPaths.CommonFiles);
      break;
    // etc...

You should remove the reference to the AfterSelect event.

Upvotes: 0

Related Questions