- Moving Data between Lists
- Making an Adapter
- Using the DataGrid
- Using a TreeView
- The Class Adapter
- Thought Question
Using the DataGrid
To circumvent the problem with the tab columns in the simple list box, we can turn to a grid display. The grid table that comes with Visual Studio.NET is called the DataGrid. It can be bound to a database or to an in-memory data array. To use the DataGrid without a database, you create an instance of the DataTable class and add DataColumns to it. DataColumns are by default of string type, but you can define them to be of any type when you create them. Here is the general outline of how you create a DataGrid using a DataTable.
DataTable dTable = new DataTable("Kids"); dTable.MinimumCapacity = 100; dTable.CaseSensitive = false; DataColumn column = new DataColumn("Frname",System.Type.GetType("System.String")); dTable.Columns.Add(column); column = new DataColumn("Lname", System.Type.GetType("System.String")); dTable.Columns.Add(column); column = new DataColumn("Age", System.Type.GetType("System.Int16")); dTable.Columns.Add(column); dGrid.DataSource = dTable; dGrid.CaptionVisible = false; //no caption dGrid.RowHeadersVisible = false; //no row headers dGrid.EndInit();
To add text to the DataTable, you ask the table for a row object and then set the elements of the row object to the data for that row. If the types are all String, then you copy the strings, but if one of the columns is of a different type, such as the integer age column here, you must be sure to use that type in setting that column's data. Note that you can refer to the columns by name or by index number.
DataRow row = dTable.NewRow(); row["Frname"] = sw.getFrname(); row[1] = sw.getLName(); row[2] = sw.getAge(); //This one is an integer dTable.Rows.Add(row); dTable.AcceptChanges();
However, we would like to be able to use the grid without changing any of the code we used for the simple list box. We do this by creating a GridAdapter that follows that same interface.
public interface LstAdapter { void Add(Swimmer sw) ; int SelectedIndex() ; void Clear() ; void clearSelection() ; }
The GridAdapter class implements this interface and is instantiated with an instance of the grid.
public class GridAdapter:LstAdapter { private DataGrid grid; private DataTable dTable; private int row; //----- public GridAdapter(DataGrid grd) { grid = grd; dTable = (DataTable)grid.DataSource; grid.MouseDown += new System.Windows.Forms.MouseEventHandler (Grid_Click); row = -1; } //----- public void Add(Swimmer sw) { DataRow row = dTable.NewRow(); row["Frname"] = sw.getFrname(); row[1] = sw.getLName(); row[2] = sw.getAge(); //This one is an integer dTable.Rows.Add(row); dTable.AcceptChanges(); } //----- public int SelectedIndex() { return row; } //----- public void Clear() { int count = dTable.Rows.Count ; for(int i=0; i< count; i++) { dTable.Rows[i].Delete (); } } //----- public void clearSelection() {} }
Detecting Row Selection
The DataGrid does not have a SelectedIndex property, and the rows do not have Selected properties. Instead, you must detect a MouseDown event with a MouseEvent handler and then get the HitTest object and see if the user has clicked on a cell.
public void Grid_Click(object sender, MouseEventArgs e) { DataGrid.HitTestInfo hti = grid.HitTest (e.X, e.Y); if(hti.Type == DataGrid.HitTestType.Cell ){ row = hti.Row ; } }
Note that we can now simply call the GridAdapter class's Add method when we click on the [Right Arrow] button, regardless of which display control we are using.
private void btClone_Click(object sender, System.EventArgs e) { int i = lskids.SelectedIndex (); if( i >= 0) { Swimmer sw = swdata.getSwimmer (i); lsNewKids.Add (sw); lskids.clearSelection (); } }
We see the final grid display in Figure 14-2.
Figure 14-2 A grid adapter