2

I keep getting this error message whenever a treenode is clicked on:

An unhandled exception of type 'System.NullReferenceException' occurred in Picture-Resize.exe Additional information: Object reference not set to an instance of an object.

My code is as follows:

public Form1()
{
    InitializeComponent();
    this.treeView1.NodeMouseClick += new TreeNodeMouseClickEventHandler (this.treeView1_NodeMouseClick);
    PopulateTreeView();
}

private void PopulateTreeView()
{
   TreeNode rootNode;

   DirectoryInfo info = new DirectoryInfo(@"c:\\");
   if (info.Exists)
   {
       rootNode = new TreeNode(info.Name);
       rootNode.Tag = info;
       GetDirectories(info.GetDirectories(), rootNode);
       treeView1.Nodes.Add(rootNode);
   }
}

private void GetDirectories(DirectoryInfo[] subDirs, TreeNode nodeToAddTo)
{
   TreeNode aNode;
   DirectoryInfo[] subSubDirs;
   foreach (DirectoryInfo subDir in subDirs)
   {
       aNode = new TreeNode(subDir.Name, 0, 0);
       aNode.Tag = subDir;
       aNode.ImageKey = "folder";
       try
       {
           /*  subSubDirs = subDir.GetDirectories();
             if (subSubDirs.Length != 0)
             {
                 GetDirectories2(subSubDirs, aNode);
             }*/
       }
       catch (System.UnauthorizedAccessException)
       {
           subSubDirs = new DirectoryInfo[0];
       }
       nodeToAddTo.Nodes.Add(aNode);
   }
}


void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{               
   //if (treeView1.SelectedNode.Nodes.Count > 0) { MessageBox.Show("Child node exists"); } else { MessageBox.Show("Child Node does not exist"); }

   try
   {
       TreeNode newSelected = e.Node;
     //  treeView1.SelectedNode.Nodes.Add("test");

       listView1.Items.Clear();
       DirectoryInfo nodeDirInfo = (DirectoryInfo)newSelected.Tag;
       ListViewItem.ListViewSubItem[] subItems;

       ListViewItem item = null;

       foreach (DirectoryInfo dir in nodeDirInfo.GetDirectories())
       {
           item = new ListViewItem(dir.Name, 0);
           subItems = new ListViewItem.ListViewSubItem[]
            {new ListViewItem.ListViewSubItem(item, "Directory"), 
             new ListViewItem.ListViewSubItem(item, 
                dir.LastAccessTime.ToShortDateString())};
           item.SubItems.AddRange(subItems);
           listView1.Items.Add(item);
       }
       foreach (FileInfo file in nodeDirInfo.GetFiles())
       {
           item = new ListViewItem(file.Name, 1);
           subItems = new ListViewItem.ListViewSubItem[]
            { new ListViewItem.ListViewSubItem(item, "File"), 
             new ListViewItem.ListViewSubItem(item, 
                file.LastAccessTime.ToShortDateString())};

           item.SubItems.AddRange(subItems);
           listView1.Items.Add(item);
       }

       listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
   }
   catch (Exception ex)
   {
        if (ex is System.NullReferenceException || ex is System.UnauthorizedAccessException)
        {
        }
   }
}

What happens is the exception handler catches it, but because an exception was thrown it requires the user to click twice for the click handler to take effect.

Why am I getting this error, and how do I avoid it?

Brad Rem
  • 6,036
  • 2
  • 25
  • 50
TK421
  • 801
  • 5
  • 16
  • 24
  • At which line of code is the exception being thrown – Ben Narube Jun 22 '13 at 13:37
  • this kind of exception is very easy to debug and fix, you should point out (highlight) the code line where the exception is thrown. Without knowing the code line I don't think anyone here can (feel free to) track down everything from the beginning to the end of your NodeMouseClick event handler to help you. – King King Jun 22 '13 at 14:49
  • I copied your code, it works without any exceptions! – Masoud Jun 22 '13 at 14:54
  • The exception is being thrown at the line I have commented out: (sorry for the confusion) `//if (treeView1.SelectedNode.Nodes.Count > 0) { MessageBox.Show("Child node exists"); } else { MessageBox.Show("Child Node does not exist"); }` – TK421 Jun 22 '13 at 16:15

2 Answers2

6

You need to debug your code.

I assume you are using Visual Studio, if so then do this:

  1. Go to the Debug menu.
  2. Click on the the Exceptions... choice.
  3. The following dialog should appear: enter image description here

Note the Common Language Runtime Exceptions checkbox is checked.

Upon clicking OK, now when you debug your code anytime an exception is thrown by your code or the .NET Framework, the debugger will halt on the line that threw the exception. This makes finding where something is "breaking" much easier.

Karl Anderson
  • 34,606
  • 12
  • 65
  • 80
2
  //if (treeView1.SelectedNode.Nodes.Count > 0)

That is indeed wrong. A node isn't selected until after the NodeMouseClick event fires. So this code is likely to bomb with NRE if there wasn't a selection yet. And requires clicking twice since the first click gives the previously selected node.

You should instead use the e.Node property, it gives you the node that was clicked. The intention of the code is a bit unclear, strong odds that you actually should be using the AfterSelect event instead. So it still works when the user uses the keyboard to select nodes.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536