DataGrid skills (3)
-------- How to implement a drop-down list
Sometimes I listen to some friends complaining that .NET's DataGrid is not very easy. As far as my personal experience, DataGrid's function is very powerful, which can make us complete a variety of work, but unfortunately, it is not simple enough. I have accumulated some solutions to some problems that I often encountered, and now I summarize them for your reference. One problem that often encounters is: We want to have such a drop-down list when editing cell content, as shown in Figure 1:
figure 1
Idea: 1 Write a class ComboForm to represent the drop-down list, the class contains two members: Form form and DataGrid components. 2 Write a class NokeyupComboBox (inherited ComboBox), the purpose is to block the WM_KEYUP message to avoid problems when pressing the Tab. 3 Write a class inherited in DataGridTextBoxColumn, named DataGridComboFormColumn. Add a ComboBox and a COMBOFORM in the class, the class implementation below: A Edit the cell content when the cell content is displayed, and the drop-down time display the drop-down list ComboForm; c Mouse Click the drop-down list, hide the Comboform and select the user. The content written in the unit (of course, you can also set up additional hidden drop-down list, such as pressing the Enter key); D drop-down list ComboForm hides when there is no focus.
Code: // comboForm class: public class comboForm: Form {private DataGrid dataGrid; public DataGrid DataGrid {get {return dataGrid;} set {dataGrid = value;}} public comboForm () {this.FormBorderStyle = FormBorderStyle.None; this. StartPosition = formstartPosition.manual; DataGrid = new datagrid (); this.controls.add (datagrid); dataGrid.dock = DockStyle.Fill; DataGrid.captionvisible = false;}}
// NoKeyUpComboBox class: public class NoKeyUpComboBox: ComboBox {const int WM_KEYUP = 0x101; protected override void WndProc (ref Message msg) {if (msg.Msg == WM_KEYUP) return; base.WndProc (ref msg);}}
// DataGridComboFormColumn class: public class DataGridComboFormColumn: DataGridTextBoxColumn {private NoKeyUpComboBox comboBox; private CurrencyManager _source; private int rowNum; private comboForm frm; public comboForm Frm {get {return frm;}} // we will use the attribute Index represents the cell content content of index column drop-down list associated private int index; public int index {get {return index;} set {index = value;}} public DataGridComboFormColumn () {frm = new comboForm (); comboBox = new NoKeyUpComboBox () ; frm.Deactivate = new EventHandler (frm_deactive); frm.DataGrid.Click = new EventHandler (grid_click); this.comboBox.DropDown = new EventHandler (comboBox_dropDown); this.comboBox.Leave = new EventHandler (comboBox_leave);} // hide private void frm_deactive (object sender, EventArgs e) {frm.Hide when the drop-down list // --Frm does not have focus; hide private void comboBox_leave (object sender, EventArgs e) {comboBox.Visible = false} does not have focus when comboBox (); ComboBox.visible = false;} // ComboBox cleales the drop-down list - FRM Private Void ComboBox_Dropdown (Object Sender, Eventa RGS E) {// Here you can also define the location of the drop-down list by the length of the drop-down list, frm.left = ComboBox.PointToscreen (NEW POINT (0, ComboBox.Height)). x; frm.top = ComboBox.PointToscreen (New Point (0, ComboBox.Height)). Y; fm.show (); frm.bringtofront ();} // When you click the DataGrid of the drop-down list, the selected content is written into the unit and hide dropdown --Frm private void grid_click (object sender, EventArgs e) {BindingManagerBase cm = frm.BindingContext [Frm.DataGrid.DataSource, frm.DataGrid.DataMember]; comboBox.Text = ((DataRowView) cm.Current) [index ] .Tostring (); this.textBox.text = (DATAROWVIEW) cm.current [index] .tostring (); frm.hide (); comboBox.visible = false; this.setColumnValueatrow (_Source, rownum, this. TEXTBOX.TEXT);} // Overload Edit method,
Instead of using comboBox TextBox protected override void Edit (CurrencyManager dataSource, int rowNum, Rectangle bounds, bool readOnly, string instanttext, bool cellVisible) {base.Edit (dataSource, rowNum, bounds, readOnly, instanttext, cellVisible); comboBox.Parent = this .TextBox.Parent; ComboBox.LEFT = this.textBox.Left-2; ComboBox.top = this.textBox.top-2; ComboBox.Size = new size (this.TextBox.width, this.comboBox.Height); ComboBox .Text = this.textbox.text; this.textbox.visible = false; combobox.visible = true; comboBOX.BRINGTOFRONT (); comboBox.focus (); _Source = dataource;} = rownum;}}
The following example shows how to use the DataGridComboFrom class: New Windows application, join SQLConnection, join the SQL database Northwind, join the following code.
private void Form1_Load (object sender, System.EventArgs e) {SqlDataAdapter da = new SqlDataAdapter ( "select ProductName from Products", this.sqlConnection1); DataSet ds = new DataSet (); da.Fill (ds, "products"); DataSet DS_COMBO = New DataSet (); da.selectcommand = New SqlCommand ("Select ProductName, QuantityPerunit, Unitprice from Products", this.sqlConnection1); Da.Fill (DS_COMBO, "Products");
DataGridTableStyle dts = new DataGridTableStyle (); dts.MappingName = "products"; myDataGridColumn col = new myDataGridColumn (); col.MappingName = "ProductName"; col.Width = 100; col.Index = 0; col.HeaderText = "ProductName "
Col.frm.dataGrid.datasource = DS_COMBO; // Set Data Source of the drop-down list col.frm.dataGrid.DataMember = "Products"; dts.gridColumnStyles.add (color); this.dataGrid1.tablestyles.add (dts); This.DataGrid1.SetDataBinding (DS, "Products");