?
Solved

Specified Cast is not Valid... treeView1_AfterSelect Event

Posted on 2005-04-28
17
Medium Priority
?
3,054 Views
Last Modified: 2011-10-03
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.
0
Comment
Question by:MellowD0c
  • 6
  • 4
  • 3
  • +3
16 Comments
 
LVL 9

Assisted Solution

by:BurntSky
BurntSky earned 60 total points
ID: 13890107
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
 
LVL 21

Assisted Solution

by:Yurich
Yurich earned 60 total points
ID: 13890140
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
 
LVL 11

Assisted Solution

by:jatinderalagh
jatinderalagh earned 60 total points
ID: 13892006
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 1

Accepted Solution

by:
mwaseem2k earned 60 total points
ID: 13892426
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
 

Author Comment

by:MellowD0c
ID: 13896017
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
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13896041
Can you put the changed code and exception you are getting
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13896126
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
 

Author Comment

by:MellowD0c
ID: 13896192
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
 
LVL 3

Assisted Solution

by:Diego Pazos
Diego Pazos earned 60 total points
ID: 13897233
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
 

Author Comment

by:MellowD0c
ID: 13898089
Does the same thing.
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13899689
Provide the code for getting data in DataSet
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13899702
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
 
LVL 3

Expert Comment

by:Diego Pazos
ID: 13909732
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
 

Author Comment

by:MellowD0c
ID: 13910140
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
 
LVL 3

Expert Comment

by:Diego Pazos
ID: 13911031
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
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13914838
view = myDS.Tables["TableOutline"].DefaultView;
               view.Sort = "TestArea_ID";
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
Screencast - Getting to Know the Pipeline
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question