在“随风飘散” 博客里面,介绍了一个不错的DataGridView数据窗口控件《DataGridView数据窗口控件开发方法及其源码提供下载》,这种控件在有些场合下,还是非常直观的。因为,在一般要求客户录入数据的地方,一般有两种途径,其一是通过弹出一个新的窗口,在里面列出各种需要输入的要素,然后保存的,如下图所示;
其二就是直接在DataGridView中直接输入。这两种方式各有优劣,本文介绍采用该控件实现第二种模式的数据数据。如下图所示
这种方式,直接通过在DataGridView中下拉列表或者文本框中输入内容,每列的数据可以联动或者做限制,实现用户数据的约束及规范化。
控件只要接受了DataTable的DataSource之后,会根据列的HeadText内容,显示表格的标题及内容,应用还是比较直观方便的。
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> private void BindGridViewData(DataTable dt, DataTable dtNoRelation) { organTable = dt; noRelationTable = dtNoRelation; DataGridView dataGridView1 = new DataGridView(); this.groupBox1.Controls.Clear(); this.groupBox1.Controls.Add(dataGridView1); dataGridView1.Dock = DockStyle.Fill; dataGridView1.CellValueChanged +=new DataGridViewCellEventHandler(organDataGridView_CellValueChanged); dataGridView1.UserDeletedRow += new DataGridViewRowEventHandler(organDataGridView_UserDeletedRow); dataGridView1.AutoGenerateColumns = false; dataGridView1.Rows.Clear(); dataGridView1.Columns.Clear(); DataGridViewDataWindowColumn col1 = new DataGridViewDataWindowColumn(); col1.HeaderText = "机构代码"; col1.Name = "机构代码"; //下拉列表的数据 col1.DataSource = GetDataTable(dtNoRelation); dataGridView1.Columns.Add(col1); DataGridViewTextBoxColumn col2 = new DataGridViewTextBoxColumn(); col2.HeaderText = "机构名称"; col2.Name = "机构名称"; col2.Width = 300; col2.ReadOnly = true; dataGridView1.Columns.Add(col2); if (dt != null) { foreach (DataRow dr in dt.Rows) { string value = dr[0].ToString(); DataGridViewRow row = new DataGridViewRow(); DataGridViewDataWindowCell cell = new DataGridViewDataWindowCell(); cell.Value = value; row.Cells.Add(cell); cell.DropDownHeight = 400; cell.DropDownWidth = 300; DataGridViewTextBoxCell cell2 = new DataGridViewTextBoxCell(); cell2.Value = dr[1].ToString(); row.Cells.Add(cell2); dataGridView1.Rows.Add(row); } } }
由于列之间的数据输入等相关的影响需要处理,因此控件的处理方式是通过委托函数进行处理,如上面的部分代码中就是处理这些事件的。
dataGridView1.CellValueChanged +=new DataGridViewCellEventHandler(organDataGridView_CellValueChanged); dataGridView1.UserDeletedRow += new DataGridViewRowEventHandler(organDataGridView_UserDeletedRow);
由于本例子是通过输入内容后,及时更新数据库及控件的显示,因此需要对该事件进行处理,处理代码如下所示。
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> private void organDataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e) { DataGridView organDataGridView = sender as DataGridView; if (!organDataGridView.IsCurrentCellInEditMode) return; #region 显示关联机构名称 if (e.RowIndex > -1) { if (organDataGridView.CurrentCell.Value == System.DBNull.Value) { return; } if (e.ColumnIndex == 0) { DataGridViewCell cell = organDataGridView.Rows[e.RowIndex].Cells["机构代码"]; if (cell.Value == null) return; string organCode = cell.Value.ToString(); string organName = GetOrganName(organTable, organCode); if (string.IsNullOrEmpty(organName)) { organName = GetOrganName(noRelationTable, organCode); } organDataGridView.Rows[e.RowIndex].Cells["机构名称"].Value = organName; } } #endregion if (this.treeView1.SelectedNode != null) { string gjOrganCode = this.treeView1.SelectedNode.Tag.ToString(); if (!string.IsNullOrEmpty(gjOrganCode)) { string yctOrganCode = organDataGridView.CurrentCell.Value.ToString(); OrganCodeMapDAL organMapDal = new OrganCodeMapDAL(); organMapDal.UpdateOrganMapData(gjOrganCode, yctOrganCode); } } } private void organDataGridView_UserDeletedRow(object sender, DataGridViewRowEventArgs e) { DataGridView organDataGridView = sender as DataGridView; string organCode = e.Row.Cells[0].Value.ToString(); OrganCodeMapDAL organMapDal = new OrganCodeMapDAL(); organMapDal.DeleteOrganMapData(organCode); }
另外,该控件还提供了一个用于对话框窗体中的复杂下拉列表的数据显示方式,控件支持内容的过滤检索,非常方便实用,如下所示
该控件的使用代码如下所示:
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> private void BindData() { //设置DataWindow属性 this.dataWindow1.PopupGridAutoSize = false; this.dataWindow1.DropDownHeight = 300; this.dataWindow1.DropDownWidth = 240; this.dataWindow1.FormattingEnabled = true; this.dataWindow1.sDisplayField = "车辆编码,车牌号码"; this.dataWindow1.sDisplayMember = "车辆编码"; this.dataWindow1.sValueMember = "车辆编码"; this.dataWindow1.SeparatorChar = "|"; BusDAL busDal = new BusDAL(); DataTable dt = busDal.GetYCTBusTable(this.txtOrganName.Tag.ToString()); this.dataWindow1.DataSource = dt; this.dataWindow1.AfterSelector += new EventHandler(dataWindow1_AfterSelector); //必须在DataSource绑定之后设置该属性 this.dataWindow1.RowFilterVisible = true; } //选择完下拉表格后执行的事件 private void dataWindow1_AfterSelector(object sender, EventArgs e) { }