Specified Cast is not Valid... treeView1_AfterSelect Event

in form load i have following event handler:

//Populate Treeview Control with Table Outline and its child related tables

                        TreeNode nodeOutline, nodeCases;
                  
                        foreach (DataRow rowOutline in myDS.Tables["TableOutline"].Rows)
                        {
                              nodeOutline = new TreeNode();
                              nodeOutline.Text = Convert.ToString(rowOutline["TestArea"]);
                              nodeOutline.Tag = rowOutline["TestArea_ID"];
                              treeView1.Nodes.Add(nodeOutline);
                              foreach (DataRow rowCases in rowOutline.GetChildRows("OutlineToCases"))
                              {
                                    nodeCases = new TreeNode();
                                    nodeCases.Text = Convert.ToString(rowCases["TestCaseName"]);
                                    nodeCases.Tag = rowCases["TestCase_ID"];
                                    nodeOutline.Nodes.Add(nodeCases);
                              }
                        }


treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(treeView1_AfterSelect);

and rest of related code...

private void treeView1_Click( object sender, EventArgs e )
            {
                  treeView1.SelectedNode =
                        treeView1.GetNodeAt( treeView1.PointToClient( Cursor.Position ) );
            }


private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
            {
                  try
                  {
                        //get the binding manager to set the position
                        BindingManagerBase bind = BindingContext[myDS, "TableOutline"];

                        DataRow row = (DataRow) treeView1.SelectedNode.Tag;
      
                        int wantedID = int.Parse(row["TestArea_ID"].ToString());
                        bind.Position= view.Find(wantedID);
                  }
                  catch (Exception ex)
                  {
                        MessageBox.Show(ex.Message + "\n" +
                              ex.Source + "\n" +
                              ex.StackTrace + "\n" +
                              ex.HelpLink + "\n"  +
                              ex.InnerException      + "\n") ;
                  }      

            }

In the above code, i get the following error message:

DataRow row = (DataRow) treeView1.SelectedNode.Tag;   <--- throws error saying:

Specified cast is not valid.
myTCM
   at myTCM.frmChild1.treeView1_AfterSelect(Object sender, TreeViewEventArgs e) in c:\solutions\mytcm\forms\frmchild1.cs:line 2912


Basically, i have code to handle parent child notes for treeview that get data from database and build list of it in treeview. I have tried to bind it to datagrid that displays data related to whichever node is selected. On checking child nodes the above afterselect event fires up and throws error on that line. How is that cast invalid?

My intention is to detect value selected in treeview control and to automatically select related value in datagrid. But the above happens and i am clueless as to why does it happen.
MellowD0cAsked:
Who is Participating?
 
mwaseem2kConnect With a Mentor Commented:
I agree with jatinderalagh
you also can try this, if you want to get whole DataRow object (not only TestArea_ID) in treeView1_AfterSelect

in your foreach loop replace
 -- > nodeOutline.Tag = rowOutline["TestArea_ID"];
By
-- > nodeOutline.Tag = rowOutline;

0
 
BurntSkyConnect With a Mentor Commented:
The reason it's invalid is because in your foreach loop at the top you don't assign a DataRow to the TreeNode's Tag property:

nodeOutline.Tag = rowOutline["TestArea_ID"];

You're assigning the value in the "TestArea_ID" field in the DataRow; not actually the DataRow itself.
0
 
YurichConnect With a Mentor Commented:
is value in the treeview related to the number of the row or to the value inside this row?

in the former case, you can try the following:

int row = Convert.ToInt32( treeView1.SelectedNode.Tag );   // convert your tag into int first
// presumably your datagrid is dg
dg.CurrentRowIndex = row;

in the latter, you'll have to iterate through your datagrid checking your value vs values in your datagrid:

int yourValue = Convert.ToInt32( treeView1.SelectedNode.Tag );
int row = 0;
for( int i = 0; i < DataGrid.Count; i++ )
{
    if( Convert.ToInt32( DataGrid[ i, yourColumnNumber ]) == yourValue )
    {
          row = i;
          break;
    }
}

regards
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
jatinderalaghConnect With a Mentor Commented:
try replacing this

   DataRow row = (DataRow) treeView1.SelectedNode.Tag;
   int wantedID = int.Parse(row["TestArea_ID"].ToString());

 by

    int wantedID = int.Parse(treeView1.SelectedNode.Tag.ToString());
0
 
MellowD0cAuthor Commented:
jatinderalagh , i tried your clue, but i don't see how it is any different than what i am already doing. Doesn't work either, i still get same error

mwaseem2k you pointed out the same thing that BurntSky pointed out. But doing so doesn't change anything. I don't get any error, but then again it doesn't do anything at all either.

Yurich, by your trick (and i have seen that before), it starts pointing in all the wrong places as it won't be using currencymanager's pointer or something. So by doing this:

int row = Convert.ToInt32( treeView1.SelectedNode.Tag );   // convert your tag into int first
// presumably your datagrid is dg
dg.CurrentRowIndex = row;

It doesn't work really in the sense that it can never seem to point to exact same related table in datagrid on selecting a parent or child node from treeview.

As for your second example, "Count" property or method doesn't exist for datagrid, i know there is one for DataView, but doesn't work that way either.
0
 
jatinderalaghCommented:
Can you put the changed code and exception you are getting
0
 
jatinderalaghCommented:
What i meant was

Replace these two lines

  Remove this --->  DataRow row = (DataRow) treeView1.SelectedNode.Tag;
   Remove this ---> int wantedID = int.Parse(row["TestArea_ID"].ToString());

 by this single line of code

    int wantedID = int.Parse(treeView1.SelectedNode.Tag.ToString());

0
 
MellowD0cAuthor Commented:
Yes, thats what i did, and i don't get any response. So i set breakpoints at:

BindingManagerBase bind = BindingContext[myDS, "TableOutline"];

                        //DataRow row = (DataRow) treeView1.SelectedNode.Tag;
      
                        //int wantedID = int.Parse(row["TestArea_ID"].ToString());
int wantedID = int.Parse(treeView1.SelectedNode.Tag.ToString());    <---------------------------here
bind.Position= view.Find(wantedID); <--------------------------- and here


and it changes value for wantedID to 0x26 or whatever i select, but it doesn't appear to be shifting that to bind.Position property and, therefore, it doesn't show that location in datagrid or jump to it.
0
 
Diego PazosConnect With a Mentor Commented:
Make the code in your AfterSelect's 'try' block be:

BindingManagerBase bind = BindingContext[myDS.Tables["TableOutline"]];
int wantedID = (int)treeView1.SelectedNode.Tag;
bind.Position = view.Find(wantedID);

Hope it works for you.
0
 
MellowD0cAuthor Commented:
Does the same thing.
0
 
jatinderalaghCommented:
Provide the code for getting data in DataSet
0
 
jatinderalaghCommented:
And what's view.Find(wantedID); in here
Just put a break point in here and check the value of wantedID. Is it the one you are expecting or some garbage
0
 
Diego PazosCommented:
Really no way. I have the code working by just copy-pasting your code and changing those three lines.
Did you really copy them into your code or you just looked over it trying to see the changes?
Note the assignment to 'bind' is different, and that is precisely what makes the positioning in the grid work.
0
 
MellowD0cAuthor Commented:
jatinderalgh, getting data from dataset is not the problem. I have actually 2 list controls to do same thing as treeview should for Parent and child tables in another tab. And on selecting either of them they are binding to datagrid's correct position at all times. Anywhere i click on either parent or child listbox items, it correctly reflects that in datagrid. Not only datagrid but also in other simple binding type Text boxes as well. They too reflect correct data in them.

The thing is simply that treeView doesn't implement IList, which is why i cannot just bind it to currencymanager position as i can for datagrid, list and comboboxes. So i found this way online to do the trick for treeView. But it just doesn't seem to work, not in C# at least.

Here is where i got the code from a while ago...

http://weblogs.asp.net/rosherove/articles/9088.aspx

private DataView view = new DataView(m_ds.Tables["Stuff"]);

//make it sort based on the PK

view.Sort="ID";

 
//Handling a listbox event

private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e)

{

      //get the binding manager to set the position

      BindingManagerBase bind = BindingContext[m_ds,"Stuff"];

 

      //Using the 'Find' of the DataView

      //returns the needed row index!

      //Just make sure you bind the ValueMember

      //property of the listbox

      bind.Position= view.Find(listBox1.SelectedValue);

}

 

//Handling a TreeView event

private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)

{

      //get the binding manager to set the position

      BindingManagerBase bind = BindingContext[m_ds,"Stuff"];

      DataRow row = (DataRow)treeView1.SelectedItem.Tag;                             <-----------------------throws error that specified cast is invalid.

      int wantedID = int.Parse(row["ID"].ToString());

      bind.Position= view.Find(wantedID);                                          

}

I guess it was jatinderalgh who asked what is view? The above code shows that and i have similar stuff for that too:


                  view = new DataView(myDS.Tables["TableOutline"]);
                  view.Sort = "TestArea_ID";


On setting break point on:

int wantedID = (int)treeView1.SelectedNode.Tag;

I can see that "treeView1.SelectedNode.Tag;" shows correct text, and wantedID does seem to get the right value passed to it as well, but when you come to next line:

bind.Position= view.Find(wantedID);  

bind.Position property doesn't just reflect what is in wantedID variable and never switches to the right item, or any item for that matter.
0
 
Diego PazosCommented:
I'll just say it once again before giving up.

YOU'RE INCORRECTLY GETTING THE BINDING MANAGER FOR THE FORM.

The line that reads

BindingManagerBase bind = BindingContext[myDS, "TableOutline"];

should read

BindingManagerBase bind = BindingContext[myDS.Tables["TableOutline"]];

That's it for me. uKER out.
0
 
jatinderalaghCommented:
view = myDS.Tables["TableOutline"].DefaultView;
               view.Sort = "TestArea_ID";
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.