Winform传统DataGridView和DevExpress控件的GridControl两者表头全选功能的实现(源码提供)

在开发一个个人项目的时候,有客户反映默认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(1515);
                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();
    }

 

包括两个界面样式的详细例子的源码地址如下:http://files.cnblogs.com/wuhuacong/TestGridViewCheck.rar 

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

 

 

主要研究技术:代码生成工具、Visio二次开发、送水管理软件等共享软件开发
专注于Winform开发框架、WCF开发框架的研究及应用。
  转载请注明出处:
撰写人:伍华聪  http:
//www.iqidi.com 
    

posted on 2011-12-30 19:49 伍华聪 阅读(1956) 评论(8) 编辑 收藏

评论

#1楼  回复 引用 查看   

每个人只能做很少的事,做精。
2011-12-30 20:56 | 海南.胡勇      

#2楼  回复 引用 查看   

恩,不错,功能已经实现了,完全够用
但为了更好的通用、移植,是不是可以做个继承于DataGridViewColumnHeaderCell的 DatagridViewCheckBoxHeaderCell的控件,
调用时直接这样就可以
 #region dgv 添加checkBox 表头
        public void addCheckCol()
        {
            DataGridViewCheckBoxColumn colCB = new DataGridViewCheckBoxColumn();
            DatagridViewCheckBoxHeaderCell cbHeader = new DatagridViewCheckBoxHeaderCell();
            colCB.HeaderCell = cbHeader;
                     dataGridView1.Columns.Insert(0, colCB);
            dataGridView1.Columns[0].Width = 40;

            cbHeader.OnCheckBoxClicked += new CheckBoxClickedHandler(cbHeader_OnCheckBoxClicked);
        }

        public void cbHeader_OnCheckBoxClicked(bool HeaderCheck)
        {
            // 根据头设置DGV的选择情况
            foreach (DataGridViewRow dr in dataGridView1.Rows)
            {
                dr.Cells[0].Value = HeaderCheck;
            }
        }
        #endregion
2011-12-31 08:09 | loghu      

#3楼[楼主]  回复 引用 查看   

@loghu
非常不错,谢谢你的宝贵建议
2011-12-31 08:33 | 伍华聪      

#4楼  回复 引用 查看   

非常棒,一直需要喔
2011-12-31 09:22 | 海风科技      

#5楼  回复 引用 查看   

@loghu
引用loghu:
恩,不错,功能已经实现了,完全够用
但为了更好的通用、移植,是不是可以做个继承于DataGridViewColumnHeaderCell的 DatagridViewCheckBoxHeaderCell的控件,
调用时直接这样就可以[code=csharp]
#region dgv 添加checkBox 表头
public void addCheckCol()
{
DataGridViewCheckBoxColumn colCB = new DataGridViewCheckBoxColumn();
...


cp上有人实现了的。。。
http://www.codeproject.com/KB/grid/CheckBoxHeaderCell.aspx
2011-12-31 10:09 | 祭天      

#6楼  回复 引用 查看   

你好,这种方式如何或者选中列的标识列数据或者选中行数据?
2012-02-08 21:19 | garfieldzf      

#7楼  回复 引用 查看   

下载了你的demo,多谢!
2012-02-08 21:23 | garfieldzf      

#8楼  回复 引用 查看   

repositoryItemCheckEdit1 需要在那里添加和设置?
2012-02-08 22:16 | garfieldzf      

导航

<2011年12月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

公告

昵称:伍华聪
园龄:6年7个月
荣誉:推荐博客
粉丝:676
关注:23

搜索

 

常用链接

最新随笔

我的标签

随笔档案(202)

文章分类(14)

文章档案(15)

相册

我的好友

我的技术支持站点(http://www.iqidi.com)

积分与排名

  • 积分 - 629355
  • 排名 - 79

最新评论

阅读排行榜

评论排行榜

推荐排行榜