[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

DataGrid - Currency Manager

Posted on 2005-04-28
29
Medium Priority
?
1,135 Views
Last Modified: 2013-12-03
Hi All,

Trying to keep the same row selected after sorting a data grid, I found the following code online:


public class MyForm : Form
{
  private int currentlySelectedRowId = -1;

  public MyForm()
  {
    this.InitializeComponent();

    // Get the CurrencyManager for the bound DataTable
    CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.myDataGrid.BindingContext[this.myDataTable];

    // Hook up to the ItemChanged event
    dataTableCurrencyManager.ItemChanged += new ItemChangeEventHandler(this.myDataTableCurrencyManager_ItemChanged);
  }

  private void myDataGrid_MouseUp(object sender, MouseEventArgs args)
  {
    DataGrid.HitTestInfo hitTestInfo = this.myDataGrid.HitTest(args.X, args.Y);

    if(hitTestInfo.Type == DataGrid.HitTestType.ColumnHeader)
    {
      // Get the CurrencyManager for the bound DataTable
      CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.myDataGrid.BindingContext[this.myDataTable];

      // Get the current DataRowView
      DataRowView currentRowView = (DataRowView)dataTableCurrencyManager.Current;                                                              //  <---- LOOK HERE
     
      // Remember the currently selected row ID
      this.currentlySelectedRowId = (int)currentRowView["key"];
    }
  }


  private void myDataTableCurrencyManager_ItemChanged(object sender, ItemChangeEventArgs args)
  {
    // Only execute this logic if we're in the state of sorting
    if(this.currentlySelectedRowId != -1)
    {
      // Find the new position of the row now that it's been sorted
      int newPosition = this.myDataTable.DefaultView.Find(this.currentSelectedRowId);

      // Get the CurrencyManager for the bound DataTable
      CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.myDataGrid.BindingContext[this.myDataTable];

      // Change the position of the currency manager
      dataTableCurrencyManager.Position = newPosition;

      // Reset sorting state
      this.currentSelectedRowId = -1;
    }
  }
}

Getting the following error at runtime:
An unhandled exception of type 'System.IndexOutOfRangeException' occurred in system.windows.forms.dll
Additional information: No value at index -1.

Any and All help greatly appreciated.  If anyone can also explain the code, some of it is over my head.  How is it finding the current row?
0
Comment
Question by:Kyle Abrahams
  • 14
  • 13
  • +1
29 Comments
 
LVL 8

Expert Comment

by:rajaloysious
ID: 13888586
Do you have a column in your dataview named "key"

      // Remember the currently selected row ID
      this.currentlySelectedRowId = (int)currentRowView["key"];

if not put in whatever is a unique column.

cheers.

0
 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 13888988
It's Actually ID.

And yes, I do.

0
 
LVL 21

Expert Comment

by:Yurich
ID: 13890363
try to check for negative values

if( (int)currentRowView["key"] >= 0 )
     this.currentlySelectedRowId = (int)currentRowView["key"];

Any datatable has the view (dataview) which the representation of what you're seeing right now... going fom where you can find your currently selected row. Frankly saying it's not the easiest way you're using but probably more effective vs searching the datagrid for previously selected value - that'd depend on the size of you datagird.

regards
0
Technology Partners: 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!

 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 13891799
But that's just it, I click on a row, then click the data column.  The position comes back as -1 because of the header (to sort it) or am I missing something?  It always seems to be negative 1!
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13892156
Okay i will try to explain the code.

1. Your dataview has the key as primary key column.
2. In MouseUp event it checks the hittest to know whether it's a column header click or not.
3. If it's a click on Column header then it gets the currently selected row in datatable and retrieves and stores the key column value in private field currentlySelectedRowId.
4. As the result of sorting Currency manager's ItemChanged event is fired.
5. In this event it retrieves the position of a DataRow from DataView using the key field stored in currentlySelectedRowId.
6. Now Change the position of the currency manager
7. Set the currentlySelectedRowId to -1 implies no row is selected.

Now you can look at these steps and find the error. To me it looks like you might have issue with key column.

Jatinder
0
 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 13896495
Here's my code:

            private void Form_Load(int status, string ID)
            {
                  Lock_Controls();
                  cmdSave.Enabled = false;
                  cmdCancel.Text = "Refresh";
                        

        
                  SqlConnection conn = new SqlConnection();
                  conn.ConnectionString =  ConfigurationSettings.AppSettings["dbConnString"];
                  conn.Open();

                  SqlDataReader dr;

                  SqlCommand cmd = new SqlCommand();
                  cmd.CommandType = CommandType.Text;
                  cmd.CommandText = "Select c.ID, c.Name, s.ID, s.CustSiteID from Sites s Left join Customers c on s.CustID = c.ID Order by c.Name";
                  cmd.Connection = conn;
                  dr = cmd.ExecuteReader();

                  //SqlDataAdapter da = new SqlDataAdapter("SELECT c.Name, s.ID, s.CustID, s.CustSiteID, s.Adr1, s.Adr2, s.City, s.State, s.Zip, s.Fname, s.Lname, s.Phone, s.Alt, s.Fax, s.eml FROM Sites s Left Join Customers c on s.CustID = c.ID", conn);
                        
                  //da.Fill(ds, "Sites");
                        
                  DataTable dt = new DataTable();
                  dt.Columns.Add("ID",  System.Type.GetType("System.Int32"));
                  dt.Columns.Add("CustID");
                  dt.Columns.Add("Cust Name");
                  dt.Columns.Add("Cust Site ID");
                           
                  while (dr.Read())
                  {
                        DataRow r = dt.NewRow();
                        r["CustID"] = dr[0];
                        r["Cust Name"] = dr[1];
                        r["ID"] = dr[2];
                        r["Cust Site ID"] = dr[3];
                        dt.Rows.Add(r);
                  }
                        
                  conn.Close();
                  cmd.CommandText = "Select Name from Customers Order by Name";
            
                  conn.Open();
                  dr = cmd.ExecuteReader();
                  ddlCust.Items.Clear();
                  ddlCust.Items.Add("[All]");

                  while(dr.Read())
                        ddlCust.Items.Add(dr[0]);

                  dt.Columns["CustID"].ColumnMapping = MappingType.Hidden;

                  dgSites.DataSource = dt;
                  dgSites.ReadOnly = true;
                                                      



                  conn.Close();
            }
/* the above code works fine, is here for reference only.  
dt is defined as:

      private int currentlySelectedRowId = -1;
      private DataTable dt = new DataTable();

these both belong to the form.
*/
       private void dtCurrencyManager_ItemChanged(object sender, ItemChangedEventArgs args)
                  {
                        // Only execute this logic if we're in the state of sorting
                        if(this.currentlySelectedRowId != -1)
                        {
                              // Find the new position of the row now that it's been sorted
                              int newPosition = this.dt.DefaultView.Find(this.currentlySelectedRowId);
                              // Get the CurrencyManager for the bound DataTable
                              CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dgSites.BindingContext[this.dt];
                              // Change the position of the currency manager
                              dataTableCurrencyManager.Position = newPosition;

                              // Reset sorting state
                              this.currentlySelectedRowId = -1;
                        }
                  }


            private void dgSites_MouseUp(object sender, System.Windows.Forms.MouseEventArgs args)
            {
                  DataGrid.HitTestInfo hitTestInfo = this.dgSites.HitTest(args.X, args.Y);
                  
                  
                  if(hitTestInfo.Type == DataGrid.HitTestType.ColumnHeader)
                  {
                        // Get the CurrencyManager for the bound DataTable
                        CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dgSites.BindingContext[this.dt];
                        

                        // Get the current DataRowView
                        DataRowView currentRowView = (DataRowView)dataTableCurrencyManager.Current;
            
                              // Remember the currently selected row ID
                      this.currentlySelectedRowId = (int)currentRowView["ID"];
                  
                  }
            }
      }
}
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13899683
     while (dr.Read())
               {
                    DataRow r = dt.NewRow();
                    r["CustID"] = dr[0];
                    r["Cust Name"] = dr[1];
                    r["ID"] = dr[2];
                    r["Cust Site ID"] = dr[3];
                    dt.Rows.Add(r);
               }

After this add


dt.PrimaryKey = new DataColumn[] {dt.Columns["ID"]};
0
 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 13901848
added the primary key, still failing at:

  // Get the current DataRowView
            DataRowView currentRowView = (DataRowView)dataTableCurrencyManager.Current;
         
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13903438
What's the exception ?
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13903475
Just add this line for precaution

 if(dataTableCurrencyManager.Current.GetType() != typeof(DataRowView)) return;

before

// Get the current DataRowView
DataRowView currentRowView = (DataRowView)dataTableCurrencyManager.Current;

0
 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 13903779
will that really do anything though.  I mean it will fix the error but I want the rest of the code to continue.  Still getting the same exact error as in original post.  Will try your fixes soon but am 99% sure it won't work :-( (no offense, just looking at reality).  Please keep up with solutions.
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13907010
That's strange when i used the dataadapter to fill my data table then code works fine. But when I created datatable object dynamically i got the same exception a you. So we need to check what's the difference between two calls .
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13907611
I got the problem buddy it's in your code. that's why copy paste didn't work.

                  //da.Fill(ds, "Sites");
                   
--> Remove this line.               DataTable dt = new DataTable();
               dt.Columns.Add("ID",  System.Type.GetType("System.Int32"));
     


Reason for removal of line. --- >
The   DataTable dt  is declared multiple time one as global and second here in locla block. So Currency manager is not able to get the context properly


And enhancement --- >

 while (dr.Read())
               {
                    DataRow r = dt.NewRow();
                    r["CustID"] = dr[0];
                    r["Cust Name"] = dr[1];
                    r["ID"] = dr[2];
                    r["Cust Site ID"] = dr[3];
                    dt.Rows.Add(r);
               }

Before this add

dt.PrimaryKey = new DataColumn[] {dt.Columns["ID"]};



Cheers
Jatinder


0
 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 13908204
LOL, Talk about EMBARRASSINIG.  This has been driving me nuts for days, too many late nights programming.  Got lost in the code.  GREAT find.
0
 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 13908292
One last question for you.  

If I click on the primary key field it works, but if I sort by customer ID it gives me the store ID that was the primary key.

EG:

I click on ID 6 store ID ABC
I sort by store ID
I get ID x with Store ID 6

there a way to change that?
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13908490
Change your events like this

private void CurrencyManager_ItemChanged(object sender, ItemChangedEventArgs args)
            {
                  // Only execute this logic if we're in the state of sorting
                  if(this.Key != null)
                  {
                        // Find the new position of the row now that it's been sorted
                        int newPosition = this.dt.DefaultView.Find(this.Key);

                        if(newPosition != -1)
                        {
                              // Get the CurrencyManager for the bound DataTable
                              CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dataGrid1.BindingContext[this.dt];
                              // Change the position of the currency manager
                              dataTableCurrencyManager.Position = newPosition;
                        }
                        // Reset sorting state
                        this.Key = null;
                  }
            }

/ rather the currentlySelectedRowId Let the key be object type.
        object Key = null;

private void dataGrid1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                  DataGrid.HitTestInfo hitTestInfo = this.dataGrid1.HitTest(e.X, e.Y);
           
                  // Cif column header is clicked
                  if(hitTestInfo.Type == DataGrid.HitTestType.ColumnHeader)
                  {
                        // Get the CurrencyManager for the bound DataTable
                        CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dataGrid1.BindingContext[this.dt];
   
                        // Get the current DataRowView
                        DataRowView currentRowView = (DataRowView)dataTableCurrencyManager.Current;
       
                        this.Key = currentRowView[hitTestInfo.Column];
                  }
            }
0
 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 13908781
     private void dataTableCurrencyManager_ItemChanged(object sender, ItemChangedEventArgs args)
            {
                  // Only execute this logic if we're in the state of sorting
                  if(this.Key != null)
                  {
                        // Find the new position of the row now that it's been sorted
                        int newPosition = this.dt.DefaultView.Find(this.Key);

                        if(newPosition != -1)   //  <---------------------------- NEVER ENTERS THIS CODE BLOCK
                        {
                              // Get the CurrencyManager for the bound DataTable
                              CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dgSites.BindingContext[this.dt];
                              // Change the position of the currency manager
                              dataTableCurrencyManager.Position = newPosition;
                        }
                        // Reset sorting state
                        this.Key = null;
                  }
            }

      

            private void dgSites_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                  DataGrid.HitTestInfo hitTestInfo = this.dgSites.HitTest(e.X, e.Y);
           
                  // Cif column header is clicked
                  if(hitTestInfo.Type == DataGrid.HitTestType.ColumnHeader)
                  {
                        // Get the CurrencyManager for the bound DataTable
                        CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dgSites.BindingContext[this.dt];
   
                        // Get the current DataRowView
                        DataRowView currentRowView = (DataRowView)dataTableCurrencyManager.Current;
       
                        this.Key = currentRowView[hitTestInfo.Column];
                  }
            }

Did it just like you said.  (Had to modify names to wire up to my code), still not working.  

(not getting into newPosition Code Block)  

Also, some columns guaranteed not to be unique, will this work?
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13915339
Okay that wouldn't work but this will --->

Change your code according to the following.

      private void CurrencyManager_ItemChanged(object sender, ItemChangedEventArgs args)
            {
                  // Only execute this logic if we're in the state of sorting
                  if(this.Key != null)
                  {
                        // Find the new position of the row now that it's been sorted
                        int newPosition = this.dt.DefaultView.Find(this.Key);

                        if(newPosition != -1)
                        {
                              // Get the CurrencyManager for the bound DataTable
                              CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dataGrid1.BindingContext[this.dt];
                              // Change the position of the currency manager
                              dataTableCurrencyManager.Position = newPosition;

                              bool SortingDescending = (this.dt.DefaultView.Sort.ToLower().IndexOf(" desc") == -1)?false:true;

                              for(int i=newPosition; i<this.dt.Rows.Count; i++)
                              {
                                    DataRowView row =  (DataRowView)dataTableCurrencyManager.Current;
                                    int currentKeyValue = (int)row["EmployeeID"];
                                    if( currentKeyValue == this.PrimaryKey)
                                    {
                                          break;
                                    }
                                    else
                                    {            
                                          if(SortingDescending)
                                                dataTableCurrencyManager.Position ++;
                                          else
                                                dataTableCurrencyManager.Position --;

                                    }
                              }
                              
                        }
                        // Reset sorting state
                        this.Key = null;
                  }
            }

object Key = null;
int PrimaryKey = -1;

private void dataGrid1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                  DataGrid.HitTestInfo hitTestInfo = this.dataGrid1.HitTest(e.X, e.Y);
           
                  // Cif column header is clicked
                  if(hitTestInfo.Type == DataGrid.HitTestType.ColumnHeader)
                  {
                  // Get the CurrencyManager for the bound DataTable
                        CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dataGrid1.BindingContext[this.dt];
   
                        // Get the current DataRowView
                        DataRowView currentRowView = (DataRowView)dataTableCurrencyManager.Current;
       
                        this.Key = currentRowView[hitTestInfo.Column];
                        this.PrimaryKey = (int)currentRowView["EmployeeID"];
                  }
            }


Cheers
Jatinder



0
 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 13916133
Still not entering newPosition codeblock.  Is this working for you?  What am I doing wrong?

The following solution works, however very inefficient:

            private void dataTableCurrencyManager_ItemChanged(object sender, ItemChangedEventArgs args)
            {
                  // Only execute this logic if we're in the state of sorting
                  if(this.Key != null)
                  {
                        // Find the new position of the row now that it's been sorted
                        int newPosition = this.dt.DefaultView.Find(this.Key);
                        
                        newPosition = 0; // DEBUG
                        

                        if(newPosition != -1)
                        {
                              // Get the CurrencyManager for the bound DataTable
                              CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dgSites.BindingContext[this.dt];
                              // Change the position of the currency manager
                              dataTableCurrencyManager.Position = newPosition;

                              for(int i=newPosition; i<this.dt.Rows.Count; i++)
                              {
                                    DataRowView row =  (DataRowView)dataTableCurrencyManager.Current;
                                    int currentKeyValue = (int)row["ID"];
                                    if( currentKeyValue == this.PrimaryKey)
                                    {
                                          break;
                                    }
                                    else
                                    {          
                                          dataTableCurrencyManager.Position ++;
                                    }
                              }
                         
                        }
                        // Reset sorting state
                        this.Key = null;
                  }
            }

      

            private void dgSites_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                  DataGrid.HitTestInfo hitTestInfo = this.dgSites.HitTest(e.X, e.Y);
           
                  // Cif column header is clicked
                  if(hitTestInfo.Type == DataGrid.HitTestType.ColumnHeader)
                  {
                        // Get the CurrencyManager for the bound DataTable
                        CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dgSites.BindingContext[this.dt];
   
                        // Get the current DataRowView
                        DataRowView currentRowView = (DataRowView)dataTableCurrencyManager.Current;
       
                        this.Key = currentRowView[hitTestInfo.Column];
                        this.PrimaryKey = (int)currentRowView["ID"];
                  }
            }

basically start at top and always work your way down.  The FIND isn't finding anything, what's going on?
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13916197
This code is working fine for me.
0
 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 13917308
Has to be in the form load then:

   dataTableCurrencyManager = (CurrencyManager) dgSites.BindingContext[dt];
                  dataTableCurrencyManager.ItemChanged -= new System.Windows.Forms.ItemChangedEventHandler(this.dataTableCurrencyManager_ItemChanged);
                  cmdCancel.Text = "Refresh";
                        

        
                  SqlConnection conn = new SqlConnection();
                  conn.ConnectionString =  ConfigurationSettings.AppSettings["dbConnString"];
                  conn.Open();

                  SqlDataReader dr;

                  SqlCommand cmd = new SqlCommand();
                  cmd.CommandType = CommandType.Text;
                  cmd.CommandText = "Select c.ID, c.Name, s.ID, s.CustSiteID from Sites s Left join Customers c on s.CustID = c.ID Order by c.Name";
                  cmd.Connection = conn;
                  dr = cmd.ExecuteReader();

                  //SqlDataAdapter da = new SqlDataAdapter("SELECT c.Name, s.ID, s.CustID, s.CustSiteID, s.Adr1, s.Adr2, s.City, s.State, s.Zip, s.Fname, s.Lname, s.Phone, s.Alt, s.Fax, s.eml FROM Sites s Left Join Customers c on s.CustID = c.ID", conn);
                        
                  //da.Fill(ds, "Sites");
                        
                  //DataTable dt = new DataTable();
                  if(dt.Columns.Count >0)
                  {
                        dt.Clear();
                  }
                  else
                  {
                        dt.Columns.Add("ID",  System.Type.GetType("System.Int32"));
                        dt.Columns.Add("CustID", System.Type.GetType("System.String"));
                        dt.Columns.Add("Cust Name", System.Type.GetType("System.String"));
                        dt.Columns.Add("Cust Site ID",  System.Type.GetType("System.String"));
                  }
                  
                  
                  dt.PrimaryKey = new DataColumn[] {dt.Columns["ID"]};
                  dt.DefaultView.Sort = "ID";
                      
                  while (dr.Read())
                  {
                        DataRow r = dt.NewRow();
                        r["CustID"] = dr[0];
                        r["Cust Name"] = dr[1];
                        r["ID"] = dr[2];
                        r["Cust Site ID"] = dr[3];
                        dt.Rows.Add(r);
                  }
            
                  conn.Close();
                  cmd.CommandText = "Select Name from Customers Order by Name";
            
                  conn.Open();
                  dr = cmd.ExecuteReader();
                  ddlCust.Items.Clear();
                  ddlCust.Items.Add("[All]");

                  while(dr.Read())
                        ddlCust.Items.Add(dr[0]);

                  dt.Columns["CustID"].ColumnMapping = MappingType.Hidden;

                  dgSites.DataSource = dt;
                  dgSites.ReadOnly = true;
                                                      



                  conn.Close();
                  dataTableCurrencyManager.ItemChanged += new System.Windows.Forms.ItemChangedEventHandler(this.dataTableCurrencyManager_ItemChanged); // ADDED AFTER LOADING, SAVES LIKE 30 seconds, otherwise much to slow for customer.
0
 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 13917330
I added some logic for first time vs reload . . . I need a refresh button as more than 1 instance of the app will be running at same time.  It's running pretty quick but I have a P 3.4 and everything is local, am concerned about over network and on a 600mhz.

Thanks for all the help.
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13918040
Why don't you try by pasting my code and changing the variable names as per your requirement. I am using northwind database in Sql Server for my example code. Or simply create a form place a datagrid in it and paste this code. Do the proper initialization to make it run. Then you can run this code and compare your code with it.

// Global or form level variables
private DataTable dt = new DataTable();
            object Key = null;
            int PrimaryKey = -1;

            private void Form1_Load(object sender, System.EventArgs e)
            {
                  #region Set the DataSource

                  // Setup DB-Connection
                  string ConnectionString = @"data source=jatinder\jatinder;user id=sa;password=sa;database=northwind";
                  SqlConnection conn = new SqlConnection(ConnectionString);

                  // Make a sql command to select all the customers sorted by company name
                  SqlCommand cmd = new SqlCommand();
                  cmd.CommandType = CommandType.Text;
                  cmd.CommandText = "Select * from Employees Order by FirstName";
                  
                  //Create the data table
                  dt.Columns.Add("EmployeeID",typeof(int));
                  dt.Columns.Add("First Name",typeof(string));
                  dt.Columns.Add("Last Name",typeof(string));
                  dt.Columns.Add("City",typeof(string));
                  
                  // Add the primary key constraint
                  dt.PrimaryKey = new DataColumn[] {dt.Columns["EmployeeID"]};
                  this.dt.DefaultView.ApplyDefaultSort =true;

                  // Open a Sql Connection and set it to SqlCommand object
                  conn.Open();
                  cmd.Connection = conn;

                  // Execute the reader and Fill datatable
                  SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                  while (dr.Read())
                  {
                        DataRow r = dt.NewRow();
                        r["EmployeeID"] = dr[0];
                        r["Last Name"] = dr[1];
                        r["First Name"] = dr[2];
                        r["City"] = dr[8];
                        dt.Rows.Add(r);
                  }
                  
                  // Set the data Source to DataGrid
                  this.dataGrid1.DataSource = dt;

                  // Specify the CurrencyManager for the DataTable.
                  CurrencyManager  myCurrencyManager = (CurrencyManager)this.dataGrid1.BindingContext[dt];
                  // Add event handlers.
                  myCurrencyManager.ItemChanged+=
                        new ItemChangedEventHandler(CurrencyManager_ItemChanged);
      
                  #endregion

            }

            private void CurrencyManager_ItemChanged(object sender, ItemChangedEventArgs args)
            {
                  // Only execute this logic if we're in the state of sorting
                  if(this.Key != null)
                  {
                        // Find the new position of the row now that it's been sorted
                        int newPosition = this.dt.DefaultView.Find(this.Key);

                        if(newPosition != -1)
                        {
                              // Get the CurrencyManager for the bound DataTable
                              CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dataGrid1.BindingContext[this.dt];
                              // Change the position of the currency manager
                              dataTableCurrencyManager.Position = newPosition;

                              bool SortingDescending = (this.dt.DefaultView.Sort.ToLower().IndexOf(" desc") == -1)?false:true;

                              for(int i=newPosition; i<this.dt.Rows.Count; i++)
                              {
                                    DataRowView row =  (DataRowView)dataTableCurrencyManager.Current;
                                    int currentKeyValue = (int)row["EmployeeID"];
                                    if( currentKeyValue == this.PrimaryKey)
                                    {
                                          break;
                                    }
                                    else
                                    {            
                                          if(SortingDescending)
                                                dataTableCurrencyManager.Position ++;
                                          else
                                                dataTableCurrencyManager.Position --;

                                    }
                              }
                              
                        }
                        // Reset sorting state
                        this.Key = null;
                  }
            }

       
            private void dataGrid1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                  DataGrid.HitTestInfo hitTestInfo = this.dataGrid1.HitTest(e.X, e.Y);
           
                  // Cif column header is clicked
                  if(hitTestInfo.Type == DataGrid.HitTestType.ColumnHeader)
                  {
                  // Get the CurrencyManager for the bound DataTable
                        CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dataGrid1.BindingContext[this.dt];
   
                        // Get the current DataRowView
                        DataRowView currentRowView = (DataRowView)dataTableCurrencyManager.Current;
       
                        this.Key = currentRowView[hitTestInfo.Column];
                        this.PrimaryKey = (int)currentRowView["EmployeeID"];
                  }
            }
0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13918077
And if you still get any exceptionor failure let me know.

Jatinder
0
 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 13928113
Did you one better, just using your code I created a new solution:

this.Key is not getting assigned in dataGrid1_MouseUp.
if I force this.Key to be 0,
new position always = -1.

You're using a windows app and it's working for you?




0
 
LVL 11

Expert Comment

by:jatinderalagh
ID: 13928207
Can you post code relevent to this problem only nothing else. I will check that tommorow
Cause what i posted is working code without any issues.
0
 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 13937374
         private void CurrencyManager_ItemChanged(object sender, ItemChangedEventArgs args)
          {
               // Only execute this logic if we're in the state of sorting
// because Key is null, it returns.  I forced it to be 0 for the time being to enter the code block with:
// this.Key = 0;
               if(this.Key != null)  
               {
                    // Find the new position of the row now that it's been sorted
// ALWAYS is -1 after the find.
                    int newPosition = this.dt.DefaultView.Find(this.Key);  

//because it's -1 it returns, code isn't executed and row is lost.
                    if(newPosition != -1)
                    {
                         // Get the CurrencyManager for the bound DataTable
                         CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dataGrid1.BindingContext[this.dt];
                         // Change the position of the currency manager
                         dataTableCurrencyManager.Position = newPosition;

                         bool SortingDescending = (this.dt.DefaultView.Sort.ToLower().IndexOf(" desc") == -1)?false:true;

                         for(int i=newPosition; i<this.dt.Rows.Count; i++)
                         {
                              DataRowView row =  (DataRowView)dataTableCurrencyManager.Current;
                              int currentKeyValue = (int)row["EmployeeID"];
                              if( currentKeyValue == this.PrimaryKey)
                              {
                                   break;
                              }
                              else
                              {          
                                   if(SortingDescending)
                                        dataTableCurrencyManager.Position ++;
                                   else
                                        dataTableCurrencyManager.Position --;

                              }
                         }
                         
                    }
                    // Reset sorting state
                    this.Key = null;
               }
          }

       
          private void dataGrid1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
          {
               DataGrid.HitTestInfo hitTestInfo = this.dataGrid1.HitTest(e.X, e.Y);
           
               // Cif column header is clicked
               if(hitTestInfo.Type == DataGrid.HitTestType.ColumnHeader)
               {
               // Get the CurrencyManager for the bound DataTable
                    CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dataGrid1.BindingContext[this.dt];
   
                    // Get the current DataRowView
                    DataRowView currentRowView = (DataRowView)dataTableCurrencyManager.Current;
       
                    this.Key = currentRowView[hitTestInfo.Column];  //STILL = NULL AFTER THIS LINE.
                    this.PrimaryKey = (int)currentRowView["EmployeeID"];
               }
          }

I created a new solution, using your code only:
The form loads fine, it's in the events with the data grid.
I click on a row, say row 6, then on a column, say column 2.
See comments for rest.  
0
 
LVL 11

Accepted Solution

by:
jatinderalagh earned 2000 total points
ID: 13942450
Here is the complete working code.
1. create a new solution
2. delete all the code from Form1.cs
3. paste my code given below.
4. I hope you will be having SQL Server 2000. So just change the connection string in Form load event nothing else.
Now try.  It's just not possible that code works on my machine perfectly and it crashes on another.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
namespace DataGridRowHeights
{
      public class Form1 : System.Windows.Forms.Form
      {
            private System.Windows.Forms.DataGrid dataGrid1;
            private System.ComponentModel.Container components = null;
            public Form1()
            {      InitializeComponent();      }
            protected override void Dispose( bool disposing )
            {      if( disposing )      {if (components != null) {      components.Dispose();}      }
                  base.Dispose( disposing );            }

            #region Windows Form Designer generated code
            private void InitializeComponent()
            {
                  this.dataGrid1 = new System.Windows.Forms.DataGrid();
                  ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();
                  this.SuspendLayout();
                  this.dataGrid1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
                  this.dataGrid1.DataMember = "";
                  this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
                  this.dataGrid1.Location = new System.Drawing.Point(16, 48);
                  this.dataGrid1.Name = "dataGrid1";
                  this.dataGrid1.Size = new System.Drawing.Size(580, 304);
                  this.dataGrid1.TabIndex = 0;
                  this.dataGrid1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.dataGrid1_MouseUp);
                  this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
                  this.ClientSize = new System.Drawing.Size(608, 381);
                  this.Controls.Add(this.dataGrid1);
                  this.Name = "Form1";
                  this.Text = "Form1";
                  this.Load += new System.EventHandler(this.Form1_Load);
                  ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();
                  this.ResumeLayout(false);
            }
            #endregion

            [STAThread]
            static void Main()
            {      Application.Run(new Form1());      }

            private DataTable dt = new DataTable();
            object Key = null;
            int PrimaryKey = -1;

            private void Form1_Load(object sender, System.EventArgs e)
            {
                  #region Set the DataSource
                  // Setup DB-Connection
                  string ConnectionString = @"data source=jatinder\jatinder;user id=sa;password=sa;database=northwind";
                  SqlConnection conn = new SqlConnection(ConnectionString);
                  // Make a sql command to select all the customers sorted by company name
                  SqlCommand cmd = new SqlCommand();
                  cmd.CommandType = CommandType.Text;
                  cmd.CommandText = "Select * from Employees Order by FirstName";
                  //Create the data table
                  dt.Columns.Add("EmployeeID",typeof(int));
                  dt.Columns.Add("First Name",typeof(string));
                  dt.Columns.Add("Last Name",typeof(string));
                  dt.Columns.Add("City",typeof(string));
                  // Add the primary key constraint
                  dt.PrimaryKey = new DataColumn[] {dt.Columns["EmployeeID"]};
                  //this.dt.DefaultView.ApplyDefaultSort =true;
                  this.dt.DefaultView.Sort = "EmployeeID";
                  // Open a Sql Connection and set it to SqlCommand object
                  conn.Open();
                  cmd.Connection = conn;
                  // Execute the reader and Fill datatable
                  SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                  while (dr.Read())
                  {
                        DataRow r = dt.NewRow();
                        r["EmployeeID"] = dr[0];
                        r["Last Name"] = dr[1];
                        r["First Name"] = dr[2];
                        r["City"] = dr[8];
                        dt.Rows.Add(r);
                  }
                  // Set the data Source to DataGrid
                  this.dataGrid1.DataSource = dt;
                  // Specify the CurrencyManager for the DataTable.
                  CurrencyManager  myCurrencyManager = (CurrencyManager)this.dataGrid1.BindingContext[dt];
                  // Add event handlers.
                  myCurrencyManager.ItemChanged+=
                        new ItemChangedEventHandler(CurrencyManager_ItemChanged);
                  #endregion
            }

            private void CurrencyManager_ItemChanged(object sender, ItemChangedEventArgs args)
            {
                  // Only execute this logic if we're in the state of sorting
                  if(this.Key != null)
                  {
                        // Find the new position of the row now that it's been sorted
                        int newPosition = this.dt.DefaultView.Find(this.Key);
                        if(newPosition != -1)
                        {
                              // Get the CurrencyManager for the bound DataTable
                              CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dataGrid1.BindingContext[this.dt];
                              // Change the position of the currency manager
                              dataTableCurrencyManager.Position = newPosition;
                              bool SortingDescending = (this.dt.DefaultView.Sort.ToLower().IndexOf(" desc") == -1)?false:true;
                              for(int i=newPosition; i<this.dt.Rows.Count; i++)
                              {
                                    DataRowView row =  (DataRowView)dataTableCurrencyManager.Current;
                                    int currentKeyValue = (int)row["EmployeeID"];
                                    if( currentKeyValue == this.PrimaryKey)
                                    {      break;      }
                                    else
                                    {
                                          if(SortingDescending)
                                                dataTableCurrencyManager.Position ++;
                                          else
                                                dataTableCurrencyManager.Position --;
                                    }
                              }
                        }
                        // Reset sorting state
                        this.Key = null;
                  }
            }
       
            private void dataGrid1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                  DataGrid.HitTestInfo hitTestInfo = this.dataGrid1.HitTest(e.X, e.Y);
                  // Cif column header is clicked
                  if(hitTestInfo.Type == DataGrid.HitTestType.ColumnHeader)
                  {
                        // Get the CurrencyManager for the bound DataTable
                        CurrencyManager dataTableCurrencyManager = (CurrencyManager)this.dataGrid1.BindingContext[this.dt];
                      // Get the current DataRowView
                        DataRowView currentRowView = (DataRowView)dataTableCurrencyManager.Current;
                      this.Key = currentRowView[hitTestInfo.Column];
                        this.PrimaryKey = (int)currentRowView["EmployeeID"];
                  }
            }
      }
}

0
 
LVL 41

Author Comment

by:Kyle Abrahams
ID: 14006835
Sorry Was away for a little bit.  It works . . . I'll compare code and go from there, thanks for the help.

0

Featured Post

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.

Question has a verified solution.

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

This article introduced a TextBox that supports transparent background.   Introduction TextBox is the most widely used control component in GUI design. Most GUI controls do not support transparent background and more or less do not have the…
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
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

830 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