您的位置:首页 > 其它

[收藏]关于DataGrid模板列的文章

2006-10-28 10:43 323 查看
声明:本文为收藏内容



Introduction

This article explains how to build some special user controls for
DataGrid
columns on a Windows application. The special controls are:
DataGrid ComboBox
,
DateTimePicker
and
Button
columns. In a
DataGrid
, a column style is an object that defines what the column looks and behaves like, including such things as color, font, and the presence of controls that will handle linked field in a database with the use of a
ComboBox
, a
CheckBox
and other controls. The .NET Framework includes two types of column-style classes by default: the
DataGridTextBoxColumn
and
DataGridBoolColumn
classes. A quantity of jobs you may want to achieve with the Windows Forms
DataGrid
control are, unexpectedly, more troublesome than you might expect. Principally, this is because the Windows Forms
DataGrid
control is column-based, rather than cell-based. As a result, to attain most tasks, you have to work with the columns, not the cells themselves. Hence the need to create our own set of
DataGridColumnStyle
objects that define custom column styles for the Windows Forms
DataGrid
control and add them to the
GridColumnStylesCollection
. Below is an explanation of how those three user controls might be useful:

DataGrid ComboBox Column Style

Suppose you have a database as shown below:

Student
Id
Name
Book
StudentId
BookName
DateTime
You have "StudentId", a foreign key to the "Id" field in "Student" table, and another field "BookName". Now, suppose you want to display the data of "Book" on a
DataGrid
, and don't want to display "StudentId" as integer. In addition, you need to display the name, but any editing would update the "StudentId" field. The first solution would be to create two
DataTable
s with parent-child relation, and write many instructions to display the wanted fields correctly, and update the table as needed. This needs a lot of instructions and design. Another solution would be to use a combo box, with data source as the "Student" table, display member as "Name", and value member as "Id". And any edits would display the new name, but update the "StudentId" field. Using the
DataGridComboBoxColumn
class is easy to do that, and is added as a column to the
DataGrid
easily.

DataGrid DateTimePicker Column Style

Let's take the same database example as above. In the table "Book", there's a field "DateTime" with date information. Suppose you want to edit this field in the
DataGrid
directly. One way is to write the date, in the right format, in the text box column of the
DataGrid
. This could cause errors if you mistyped the date, or in a different format. Another solution would be to use a
DateTimePicker
control, and just choose the exact date from the control. Using the
DataGridTimePickerColumn
allows you to achieve that easily.

DataGrid Button Column Style

You are viewing all rows in the
DataGrid
. Now, suppose you want to delete a row from the
DataSet
. A simple way would be to click on a button on this row, and an event is fired to delete the row, then refresh the
DataSet
. This can be easily done using
DataGridButtonColumn
.

Using the code

DataGridComboBoxColumn

This class builds the
ComboBox
column user control for
DataGrid
s for Windows applications. It inherits from
DataGridTextBoxColumn
, since this is already an available control in the .NET Framework. What needs to be modified, depending on the application, is the
Leave
event.


Collapse
private void comboBox_Leave(object sender, EventArgs e){DataRowView rowView = (DataRowView) this.comboBox.SelectedItem;string s=null;//in case the selected value is null.try{if(!rowView.Row[this.comboBox.DisplayMember].GetType().FullName.Equals("System.DBNull"))s = (string) rowView.Row[this.comboBox.DisplayMember];elses="";}catch(Exception ex){MessageBox.Show(ex.Message);//s="";}SetColumnValueAtRow(this.cmanager, this.iCurrentRow, s);Invalidate();this.comboBox.Hide();this.DataGridTableStyle.DataGrid.Scroll -=new EventHandler(DataGrid_Scroll);}

Notice that the case where the selected value is null should be handled. Null values generate
System.DBNull
as output. This has to be converted to an empty string.

To use this class, simply add it to the project, construct an instance, and use its properties. This is a sample usage:

RamiSaad.DataGridComboBoxColumn comboboxColStyle =new RamiSaad.DataGridComboBoxColumn();comboboxColStyle.ComboBox.DataSource=_dataSet.Tables["Student"];comboboxColStyle.ComboBox.DisplayMember =_dataSet.Tables["Student"].Columns["Name"].ColumnName;;comboboxColStyle.ComboBox.ValueMember =_dataSet.Tables["Student"].Columns["Id"].ColumnName;comboboxColStyle.HeaderText =  "Student Id";comboboxColStyle.MappingName =  _dataSet.Tables["Book"].Columns[i].ColumnName;tableStyle.GridColumnStyles.Add(comboboxColStyle);


Note: You must set the properties and
DataSource
of the
ComboBox
property of the user control first before setting its header text and mapping name of the column style.


DataGridTimePickerColumn

This class builds the
DateTimePicker
column user control for
DataGrid
s for Windows applications. It inherits from
DataGridTextBoxColumn
, since this is already an available control in the .NET Framework.

This is a sample usage:

RamiSaad.DataGridTimePickerColumn timepickerColStyle =new RamiSaad.DataGridTimePickerColumn();timepickerColStyle.HeaderText =  "Date";timepickerColStyle.MappingName =_dataSet.Tables["Book"].Columns[i].ColumnName;timepickerColStyle.Width=145;tableStyle.GridColumnStyles.Add(timepickerColStyle);

DataGridButtonColumn

This class builds the
Button
column user control for
DataGrid
s for Windows application. It inherits from
DataGridTextBoxColumn
, since this is already an available control in the .NET Framework. To use this class, simply add it to the project, construct an instance, and use its properties.

Images of the button and button-pressed are attached with the class as well. You can add images to the solution, and choose "embedded resource" as build action in their properties. Then, in the class constructor, you must specify the location of the images in the assembly's resources:

try{char[] c={','};System.IO.Stream strm = this.GetType().Assembly.GetManifestResourceStream(this.GetType().Assembly.ToString().Split(c,10)[0]+".button.bmp");_button = new Bitmap(strm);strm = this.GetType().Assembly.GetManifestResourceStream(this.GetType().Assembly.ToString().Split(c,10)[0]+".buttonpressed.bmp");_buttonPressed = new Bitmap(strm);}catch(Exception ex){MessageBox.Show(ex.Message);}

This class uses handles, thus the constructor includes column number in its parameter. You must specify the
DataGrid
's column number in which the button control will be inserted:

RamiSaad.DataGridButtonColumn buttonColStyle =new RamiSaad.DataGridButtonColumn(i); //pass the column#

A button click event argument class is inserted in the same control's class. This is useful to manage the messages or actions when the button is clicked:

public delegate void DataGridCellButtonClickEventHandler(object sender,DataGridCellButtonClickEventArgs e);public class DataGridCellButtonClickEventArgs : EventArgs{private int _row;private int _col;public DataGridCellButtonClickEventArgs(int row, int col){_row = row;_col = col;}public int RowIndex    {get{return _row;}}public int ColIndex    {get{return _col;}}}


Note: You must define the button click event handler
DataGridCellButtonClickEventHandler
. This will be called from the form itself which calls the
DataGrid
.


Here is a sample on how to use this class from the
DataGrid
's form:


Collapse
{buttonColStyle = new RamiSaad.DataGridButtonColumn(i); //pass the column#buttonColStyle.HeaderText =  "Delete";buttonColStyle.MappingName =  _dataSet.Tables["Book"].Columns[i].ColumnName;//hookup our cellbutton handler...buttonColStyle.CellButtonClicked +=new RamiSaad.DataGridCellButtonClickEventHandler(HandleCellButtonClick);tableStyle.GridColumnStyles.Add(buttonColStyle);//hook the mouse handlersdataGrid1.MouseDown += new MouseEventHandler(buttonColStyle.HandleMouseDown);dataGrid1.MouseUp += new MouseEventHandler(buttonColStyle.HandleMouseUp);}/////////// handler for a click on one of the gridcell buttonsprivate void HandleCellButtonClick(object sender, DataGridCellButtonClickEventArgs e){MessageBox.Show("row " + e.RowIndex.ToString() +  " will be deleted.");}


Note: The handler for a button click is inserted in the
DataGrid
's form itself. Also, you must hook the mouse handlers to the button column style.


That's all. The user controls' classes are easy to use, as explained above. Hopefully, more user controls will be added later. Please let me know of any feedback or comment on this article or code.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: