近几日,在项目中,需要实现一个如下功能:
先放截图:
根据标识SpecFlag,在gridControl中,分别生成CheckEidt和ButtonEdit。
1.思路分析
根据经验,此类设计需要在代码中进行控件的创建,并为其设置相应的事件。在代码中,根据SpecFlag进行不同控件的创建,CheckEidt和ButtonEidt的创建方式与上篇单列全部使用RepositoryCheckEdit介绍的方式相似。
2.实现过程
1.声明全局变量
DevExpress.XtraEditors.Repository.RepositoryItemCheckEdit riCheck; DevExpress.XtraEditors.Repository.RepositoryItemButtonEdit riButton;
其实也可以在,创建部分进行声明,声明地点无所谓。
2.控件创建部分
/// <summary> /// 根据specflag构造列中的按钮或checkedit /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void gridView_data_CustomRowCellEdit(object sender, DevExpress.XtraGrid.Views.Grid.CustomRowCellEditEventArgs e) { if (e.Column.Name=="SpecFlag") { SpecialFormInfoModel model = gridView_data.GetRow(e.RowHandle) as SpecialFormInfoModel; if (!string.IsNullOrEmpty(model.SpecFlag) && (model.SpecFlag == "CLL-S"/*单套载重*/ || model.SpecFlag == "CLL-M"/*多套载重*/ || model.SpecFlag == "CEX-M"/*免除*/)) { riButton = this.repositoryItemButtonEdit; e.RepositoryItem = riButton; } else { riCheck = new DevExpress.XtraEditors.Repository.RepositoryItemCheckEdit(); riCheck.NullStyle = DevExpress.XtraEditors.Controls.StyleIndeterminate.Unchecked; riCheck.ValueGrayed = false; riCheck.QueryCheckStateByValue -= riCheck_QueryCheckStateByValue; riCheck.QueryCheckStateByValue += riCheck_QueryCheckStateByValue; riCheck.QueryValueByCheckState -= riCheck_QueryValueByCheckState; riCheck.QueryValueByCheckState += riCheck_QueryValueByCheckState; riCheck.CheckedChanged += riCheck_CheckedChanged; e.RepositoryItem = riCheck; } } }
3.部分事件代码
/// <summary> /// checkedit的值转换 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void riCheck_QueryValueByCheckState(object sender, DevExpress.XtraEditors.Controls.QueryValueByCheckStateEventArgs e) { switch (e.CheckState) { case CheckState.Checked: e.Value = "True"; break; case CheckState.Indeterminate: e.Value = "False"; break; case CheckState.Unchecked: e.Value = "False"; break; default: break; } e.Handled = true; } void riCheck_QueryCheckStateByValue(object sender, DevExpress.XtraEditors.Controls.QueryCheckStateByValueEventArgs e) { string val = ""; if (e.Value!=null) { val = e.Value.ToString(); } else { val = "False"; } switch (val) { case "True": e.CheckState = CheckState.Checked; break; case "False": e.CheckState = CheckState.Unchecked; break; default: break; } e.Handled = true; }
到此,标题所要实现的功能已经完成。但是!!!我在实现,双击右侧grid数据,将左侧相应数据的check状态取消的时候,发现,左侧CheckEdit的状态无法更新,即其实际状态为UnCheck的时候,界面已然是勾选状态,这个问题搞的我持续懵逼啊,经过一轮百度和测试,就在快要放弃的时候,找到了解决方案。。。。。。。,重点来了,重点来了,重点来了。
先上代码
/// <summary> /// 双击已选列表删除本次添加数据 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void gridView_selected_DoubleClick(object sender, EventArgs e) { CommSelectorModel curModel = this.gridView_selected.GetFocusedRow() as CommSelectorModel; if (curModel.IsWorkForm == "0") { selectedList.Remove(curModel); this.listData.FirstOrDefault(o => o.Id == curModel.ID && o.FormCode == curModel.FormCode).SpecFlag = "False"; //最重要的一句,即产生作用的一句 } RefreshSel(); }
原因是:
CheckedChanged触发后并未立即更新到数据源,因此勾选的该行状态在数据源中还是True,只有在焦点离开相应行时,才能更新到数据源。但是,此时,界面焦点在右侧grid,所以导致数据如法更新,必须手动更新才行。
所以直接将数据源中需要改变状态的行的标识修改为False即可。(因为选中时,是直接点击的CheckEdit,值会自动更新)
若不太明白,看一下:
若在绑定数据源的情况下实现只可单选,可以通过循环每行的状态来实现。
/// <summary> /// 选择状态改变触发事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void repositoryItemCheckEditKey_CheckedChanged(object sender, EventArgs e) { DataTable dt = gridControlDetial.DataSource as DataTable; for (int i = 0; i < dt.Rows.Count; i++) { dt.Rows[i][0] = false; } gridControlDetial.RefreshDataSource(); }
若还不是很明白,建议动手写个demo,打断点手动调试一下,根据运行前后和结果会很清晰的帮助你理解。