在开发一个个人项目的时候,有客户反映默认GridView多选操作不是很方便和理想,想在列表的左边增加一列可以勾选,并且最好支持列表头部全选的操作,否则数据多的时候一个个勾选要到天荒地老。

基于以上需求,找了不少例子进行比较,并对代码进行测试改进,终于完成了以上的功能了, 并且由于我本身做了多套界面的处理,因此,基于传统的DataGridView全选操作不能少,而且基于DevExpress控件的GridView全选操作也应该支持,呵呵。

无图无真相,下面先上图介绍两种不同的效果,然后在详细介绍代码的实现。




1)DevExpress控件的GridView的实现多选操作

先讲DevExpress控件的GridView的实现,要实现的功能基本上是处理单击全选操作、重新绘制表头等操作,首先在加载第一步实现相关的事件和操作,如下所示。

this
.gridView1.Click +=
new
System.EventHandler(
this
.gridView1_Click);
this
.gridView1.CustomDrawColumnHeader +=
new
DevExpress.XtraGrid.Views.Grid.ColumnHeaderCustomDrawEventHandler(
this
.gridView1_CustomDrawColumnHeader);
this
.gridView1.DataSourceChanged +=
new
EventHandler(gridView1_DataSourceChanged);

然后就是实现里面的事件操作了,对应的代码如下所示。

private
void
gridView1_Click(
object
sender, EventArgs e)
{
if
(DevControlHelper.ClickGridCheckBox(
this
.gridView1,
"
Check
"
, m_checkStatus))
{
m_checkStatus = !m_checkStatus;
}
}

private
void
gridView1_CustomDrawColumnHeader(
object
sender, DevExpress.XtraGrid.Views.Grid.ColumnHeaderCustomDrawEventArgs e)
{
if
(e.Column !=
null
&& e.Column.FieldName ==
"
Check
"
)
{
e.Info.InnerElements.Clear();
e.Painter.DrawObject(e.Info);
DevControlHelper.DrawCheckBox(e, m_checkStatus);
e.Handled =
true
;
}
}
void
gridView1_DataSourceChanged(
object
sender, EventArgs e)
{
GridColumn column =
this
.gridView1.Columns.ColumnByFieldName(
"
Check
"
);
if
(column !=
null
)
{
column.Width =
80
;
column.OptionsColumn.ShowCaption =
false
;
column.ColumnEdit =
new
RepositoryItemCheckEdit();
}
}

其中单击和绘制表头的操作,交给另外一个类
DevControlHelper
来独立进行处理,数据源变化
gridView1_DataSourceChanged
实现的操作是寻找对应的全选列,并设置列宽、隐藏表头标题,并设置为复选框样式。

DevControlHelper
类的实现代码如下所示:

public
static
void
DrawCheckBox(DevExpress.XtraGrid.Views.Grid.ColumnHeaderCustomDrawEventArgs e,
bool
chk)
{
RepositoryItemCheckEdit repositoryCheck = e.Column.ColumnEdit
as
RepositoryItemCheckEdit;
if
(repositoryCheck !=
null
)
{
Graphics g = e.Graphics;
Rectangle r = e.Bounds;

DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo info;
DevExpress.XtraEditors.Drawing.CheckEditPainter painter;
DevExpress.XtraEditors.Drawing.ControlGraphicsInfoArgs args;
info = repositoryCheck.CreateViewInfo()
as
DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo;

painter = repositoryCheck.CreatePainter()
as
DevExpress.XtraEditors.Drawing.CheckEditPainter;
info.EditValue = chk;
info.Bounds = r;
info.CalcViewInfo(g);
args =
new
DevExpress.XtraEditors.Drawing.ControlGraphicsInfoArgs(info,
new
DevExpress.Utils.Drawing.GraphicsCache(g), r);
painter.Draw(args);
args.Cache.Dispose();
}
}

public
static
bool
ClickGridCheckBox(DevExpress.XtraGrid.Views.Grid.GridView gridView,
string
fieldName,
bool
currentStatus)
{
bool
result =
false
;
if
(gridView !=
null
)
{
gridView.ClearSorting();
//
禁止排序


gridView.PostEditor();
DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitInfo info;
Point pt = gridView.GridControl.PointToClient(Control.MousePosition);
info = gridView.CalcHitInfo(pt);
if
(info.InColumn && info.Column !=
null
&& info.Column.FieldName == fieldName)
{
for
(
int
i =
0
; i < gridView.RowCount; i++)
{
gridView.SetRowCellValue(i, fieldName, !currentStatus);
}
return
true
;
}
}
return
result;
}

2)传统DataGridView实现全选操作

首先在第一列增加一个CheckBox控件,然后通过相关的事件,调整其位置,并相应对应的单击全选操作,初始化代码如下所示。

CheckBox HeaderCheckBox =
null
;
public
FrmNormalGridViewSelect()
{
InitializeComponent();

if
(!
this
.DesignMode)
{
HeaderCheckBox =
new
CheckBox();
HeaderCheckBox.Size =
new
Size(
15
,
15
);
this
.dgvSelectAll.Controls.Add(HeaderCheckBox);

HeaderCheckBox.KeyUp +=
new
KeyEventHandler(HeaderCheckBox_KeyUp);
HeaderCheckBox.MouseClick +=
new
MouseEventHandler(HeaderCheckBox_MouseClick);
dgvSelectAll.CurrentCellDirtyStateChanged +=
new
EventHandler(dgvSelectAll_CurrentCellDirtyStateChanged);
dgvSelectAll.CellPainting +=
new
DataGridViewCellPaintingEventHandler(dgvSelectAll_CellPainting);
}
}

事件实现了CheckBox重绘调整,并处理单击事件,如下所示。

private
void
HeaderCheckBox_MouseClick(
object
sender, MouseEventArgs e)
{
HeaderCheckBoxClick((CheckBox)sender);
}

private
void
dgvSelectAll_CellPainting(
object
sender, DataGridViewCellPaintingEventArgs e)
{
if
(e.RowIndex == -
1
&& e.ColumnIndex ==
0
)
ResetHeaderCheckBoxLocation(e.ColumnIndex, e.RowIndex);
}

private
void
ResetHeaderCheckBoxLocation(
int
ColumnIndex,
int
RowIndex)
{
Rectangle oRectangle =
this
.dgvSelectAll.GetCellDisplayRectangle(ColumnIndex, RowIndex,
true
);
Point oPoint =
new
Point();
oPoint.X = oRectangle.Location.X + (oRectangle.Width - HeaderCheckBox.Width) /
2
+
1
;
oPoint.Y = oRectangle.Location.Y + (oRectangle.Height - HeaderCheckBox.Height) /
2
+
1
;
HeaderCheckBox.Location = oPoint;
}

private
void
HeaderCheckBoxClick(CheckBox HCheckBox)
{
foreach
(DataGridViewRow Row
in
dgvSelectAll.Rows)
{
((DataGridViewCheckBoxCell)Row.Cells[
"
chkBxSelect
"
]).Value = HCheckBox.Checked;
}
dgvSelectAll.RefreshEdit();
}

非常感谢你阅读及支持,如果有好的建议及问题,可以联系我,共同讨论促进。

标签: none

添加新评论