开发者论坛

 找回密码
 注册 (请使用非IE浏览器)
查看: 5284|回复: 4

DevExpress 自绘勾选框代码

[复制链接]

0

精华

0

贡献

18

赞扬

帖子
43
软币
239
在线时间
17 小时
注册时间
2014-4-18
发表于 2015-8-4 10:36:55 | 显示全部楼层 |阅读模式
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Act.Ui.Controls.Widget.Composite;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;

namespace Act.Ui.Controls.Widget.Composite
{
    /// <summary> DevGrid的行选择器。
    /// 作用:将为GridView添加一列勾选列。提供多选,可单选等功能;
    /// </summary>
    public class DevGridRowSelector
    {
        /// <summary>是否冻结全选列</summary>
        public bool IsFreeze
        {
            get
            {
                return _view.Columns[CheckFieldName].Fixed == FixedStyle.Left;
            }
            set
            {
                _view.Columns[CheckFieldName].Fixed = value ? FixedStyle.Left : FixedStyle.None;
            }
        }



        protected static Dictionary<GridView, DevGridRowSelector> DicInst
            = new Dictionary<GridView, DevGridRowSelector>();

        /// <summary> 为GridView设置DevGridRowChecker(重复针对同一个GridView设置,提供单体形式DevGridRowChecker实例)
        /// </summary>
        /// <param name="gridview"></param>
        /// <returns></returns>
        public static DevGridRowSelector Setup(GridView gridview)
        {
            if (!DicInst.ContainsKey(gridview))
            {
                gridview.Disposed -= new EventHandler(gridview_Disposed);
                gridview.Disposed += new EventHandler(gridview_Disposed);
                DicInst.Add(gridview, new DevGridRowSelector(gridview));
            }

            var rc = DicInst[gridview];

            rc.EnsureAttach(gridview);

            return rc;
        }

        /// <summary>为GridView设置DevGridRowChecker(重复针对同一个GridView设置,提供单体形式DevGridRowChecker实例)</summary>
        /// <param name="gridview">要设置的GridView</param>
        /// <param name="isFreeze">是否冻结全选列</param>
        /// <returns></returns>
        public static DevGridRowSelector Setup(GridView gridview, bool isFreeze)
        {
            if (!DicInst.ContainsKey(gridview))
            {
                gridview.Disposed -= new EventHandler(gridview_Disposed);
                gridview.Disposed += new EventHandler(gridview_Disposed);
                DevGridRowSelector rs = new DevGridRowSelector(gridview);
                rs.IsFreeze = isFreeze;
                DicInst.Add(gridview, rs);
            }

            var rc = DicInst[gridview];

            rc.EnsureAttach(gridview);

            return rc;
        }

        /// <summary> 获取View的DevGridRowChecker实例
        /// </summary>
        /// <param name="gridview"></param>
        /// <returns></returns>
        public static DevGridRowSelector GetInstance(GridView gridview)
        {
            if (!DicInst.ContainsKey(gridview))
            {
                Setup(gridview);
            }

            return DicInst[gridview];
        }


        /// <summary> 获取View的
        /// </summary>
        /// <param name="gridview"></param>
        /// <returns></returns>
        public static bool RemoveInstance(GridView gridview)
        {
            if (DicInst.ContainsKey(gridview))
            {
                var rc = DicInst[gridview];

                rc.Detach();

                gridview.Disposed -= new EventHandler(gridview_Disposed);
                DicInst.Remove(gridview);
                return true;
            }

            return false;
        }

        static void gridview_Disposed(object sender, EventArgs e)
        {
            GridView gv = sender as GridView;
            if (gv != null && DicInst.ContainsKey(gv))
            {
                DicInst.Remove(gv);
            }
        }


        protected GridView _view;

        /// <summary> 选中的集合
        /// </summary>
        public ArrayList Selection;

        private GridColumn _column;
        private RepositoryItemCheckEdit _edit;


        private bool _isSingleSelect;
        /// <summary> 是否单选
        /// </summary>
        public virtual bool IsSingleSelect
        {
            get { return _isSingleSelect; }
            set
            {
                this._column.OptionsColumn.ShowCaption = value;
                _isSingleSelect = value;
            }
        }


        /// <summary> 是否高亮选择行
        /// </summary>
        public virtual bool IsHighlightSelection { get; set; }

        /// <summary> 不公开构造器
        /// </summary>
        protected DevGridRowSelector()
        {
            //缺省用户可以选择
            this.CanUserSelect = true;

            Selection = new ArrayList();
        }

        /// <summary> 不公开构造器
        /// </summary>
        /// <param name="view"></param>
        protected DevGridRowSelector(GridView view)
            : this()
        {
            View = view;
        }

        /// <summary> 勾选列名
        /// </summary>
        public const string CheckFieldName = "DEVGRID_CHECK_SELECTION";

        /// <summary>
        /// </summary>
        /// <param name="gridview"></param>
        public virtual void EnsureAttach(GridView gridview)
        {
            Attach(gridview);
        }

        /// <summary> 附加勾选
        /// </summary>
        /// <param name="gridview"></param>
        public virtual void Attach(GridView gridview)
        {
            if (gridview == null)
            {
                return;
            }

            Selection.Clear();

            this._view = gridview;

            var col = _view.Columns.ColumnByFieldName(CheckFieldName);



            if (col == null)
            {
                _edit = _view.GridControl.RepositoryItems.Add("CheckEdit") as RepositoryItemCheckEdit;
                _edit.EditValueChanged += new EventHandler(edit_EditValueChanged);

                _column = gridview.Columns.Add();
                _column.OptionsColumn.AllowSort = DevExpress.Utils.DefaultBoolean.False;
                _column.Width = 20;
                _column.VisibleIndex = 0;
                _column.FieldName = CheckFieldName;
                _column.Caption = "";

                _column.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
                _column.OptionsColumn.ShowCaption = false;
                _column.UnboundType = DevExpress.Data.UnboundColumnType.Boolean;
                _column.OptionsColumn.AllowMove = false;
                _column.OptionsColumn.AllowMerge = DevExpress.Utils.DefaultBoolean.False;
                _column.ColumnEdit = _edit;

                //_view.OptionsBehavior.EditorShowMode = DevExpress.Utils.EditorShowMode.Click;

                _view.CustomDrawColumnHeader += new ColumnHeaderCustomDrawEventHandler(View_CustomDrawColumnHeader);
                _view.CustomDrawGroupRow += new RowObjectCustomDrawEventHandler(View_CustomDrawGroupRow);
                _view.CustomUnboundColumnData += new CustomColumnDataEventHandler(view_CustomUnboundColumnData);
                _view.RowStyle += new RowStyleEventHandler(view_RowStyle);
                _view.MouseDown += new MouseEventHandler(view_MouseDown);
                _view.CellValueChanged += new CellValueChangedEventHandler(gridview_CellValueChanged);
                if (IsFreeze)
                {
                    _column.Fixed = FixedStyle.Left;
                }
            }
            else
            {
                _edit = col.ColumnEdit as RepositoryItemCheckEdit;
                _column = col;
                if (!_column.Visible)
                {
                    _column.Visible = true;
                    _column.VisibleIndex = 0;
                }
                if (IsFreeze)
                {
                    _column.Fixed = FixedStyle.Left;
                }
            }

            Invalidate();
        }

        /// <summary> 去掉勾选列
        /// </summary>
        public virtual void Detach()
        {
            if (_view == null)
            {
                return;
            }
            if (_column != null)
            {
                _view.Columns.Remove(_column);
                _column.Dispose();
            }
            if (_edit != null)
            {
                _view.GridControl.RepositoryItems.Remove(_edit);
                _edit.Dispose();
            }

            _view.CustomDrawColumnHeader -= new ColumnHeaderCustomDrawEventHandler(View_CustomDrawColumnHeader);
            _view.CustomDrawGroupRow -= new RowObjectCustomDrawEventHandler(View_CustomDrawGroupRow);
            _view.CustomUnboundColumnData -= new CustomColumnDataEventHandler(view_CustomUnboundColumnData);
            _view.RowStyle -= new RowStyleEventHandler(view_RowStyle);
            _view.MouseDown -= new MouseEventHandler(view_MouseDown);
            _view.CellValueChanged -= gridview_CellValueChanged;


            _view = null;
        }

        protected virtual void DrawCheckBox(Graphics g, Rectangle r, int select)
        {
            DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo info;
            DevExpress.XtraEditors.Drawing.CheckEditPainter painter;
            DevExpress.XtraEditors.Drawing.ControlGraphicsInfoArgs args;
            info = _edit.CreateViewInfo() as DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo;
            painter = _edit.CreatePainter() as DevExpress.XtraEditors.Drawing.CheckEditPainter;
            if (select == 0)
            {
                info.EditValue = false;
            }
            else if (select == 1)
            {
                info.EditValue = true;
            }
            else
            {
                info.EditValue = select;
            }

            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();
        }

        protected virtual void gridview_CellValueChanged(object sender, CellValueChangedEventArgs e)
        {
            if (!IsSingleSelect)
            {
                return;
            }
            if (e.Column == _column)
            {
                ClearSelection();
                SelectRow(e.RowHandle, true);
            }
        }

        protected virtual void view_MouseDown(object sender, MouseEventArgs e)
        {
            if (!CanUserSelect)
            {
                return;
            }

            if (e.Clicks == 1 && e.Button == MouseButtons.Left)
            {
                GridHitInfo info;

                Point pt = _view.GridControl.PointToClient(Control.MousePosition);

                info = _view.CalcHitInfo(pt);

                if (info.InRow)
                {
                    this._view.FocusedRowHandle = info.RowHandle;
                }

                if (_view.OptionsBehavior.ReadOnly || !_view.OptionsBehavior.Editable || !_column.OptionsColumn.AllowEdit || _column.OptionsColumn.ReadOnly)
                {

                    if (info.Column == _column && _view.IsDataRow(info.RowHandle))
                    {
                        if (IsSingleSelect)
                        {
                            ClearSelection();
                            SelectRow(info.RowHandle, true);
                        }
                        else
                        {

                            SelectRow(info.RowHandle, !IsRowSelected(info.RowHandle));
                        }
                    }
                }

                if ((info.InColumn) && info.Column == _column)
                {
                    if (IsSingleSelect)
                    {
                        return;
                    }

                    int w = _view.GetColumnX(_column);
                    int s = Math.Abs(info.HitPoint.X - w);

                    //如果尺寸在勾选框中心位置附近误差10像素,则认为点上了Check框。
                    if (Math.Abs(s - (_column.VisibleWidth / 2)) > 10)
                    {
                        return;
                    }

                    if (SelectedCount == _view.DataRowCount)
                    {
                        ClearSelection();
                    }
                    else
                    {
                        SelectAll();
                    }

                    if (RowCheckChanged != null)
                    {
                        RowCheckChanged.Invoke(info.RowHandle);
                    }

                    return;
                }

                if (_view.IsGroupRow(info.RowHandle) && info.HitTest != GridHitTest.RowGroupButton)
                {

                    if (!_groupRowCheckEnabled)
                    {
                        return;
                    }

                    if (IsSingleSelect)
                    {
                        return;
                    }

                    int selected = IsGroupRowSelected(info.RowHandle);
                    if (selected != 1)
                    {
                        SelectGroup(info.RowHandle, 1);
                    }
                    else
                    {
                        SelectGroup(info.RowHandle, 0);
                    }

                }
            }
        }

        /// <summary>
        /// 是否显示列头的全选
        /// </summary>
        public bool IsShowColumnCheckAll=true;

        protected virtual void View_CustomDrawColumnHeader(object sender, ColumnHeaderCustomDrawEventArgs e)
        {
            if (e.Column == _column)
            {
                e.Info.InnerElements.Clear();

                e.Painter.DrawObject(e.Info);

                if (IsSingleSelect ||
                    !IsShowColumnCheckAll)
                {
                    return;
                }

                if (SelectedCount == 0)
                {
                    DrawCheckBox(e.Graphics, e.Bounds, 0);
                }
                else if (SelectedCount == _view.DataRowCount)
                {
                    DrawCheckBox(e.Graphics, e.Bounds, 1);
                }
                else
                {
                    DrawCheckBox(e.Graphics, e.Bounds, 2);
                }
                e.Handled = true;
            }
        }

        /// <summary>
        /// </summary>
        bool _groupRowCheckEnabled;


        /// <summary> 是否在GroupRow上显示Check选择框
        /// </summary>
        public virtual bool GroupRowCheckEnabled
        {
            get
            {
                return _groupRowCheckEnabled;
            }
            set
            {
                _groupRowCheckEnabled = value;
            }
        }



        protected virtual void View_CustomDrawGroupRow(object sender, RowObjectCustomDrawEventArgs e)
        {
            if (!_groupRowCheckEnabled)
            {
                return;
            }
            if (IsSingleSelect)
            {
                return;
            }

            GridGroupRowInfo info = e.Info as DevExpress.XtraGrid.Views.Grid.ViewInfo.GridGroupRowInfo;

            info.GroupText = "         " + info.GroupText.TrimStart();
            e.Info.Paint.FillRectangle(e.Graphics, e.Appearance.GetBackBrush(e.Cache), e.Bounds);
            e.Painter.DrawObject(e.Info);

            Rectangle r = info.ButtonBounds;
            r.Offset(r.Width * 2, 0);

            int select = IsGroupRowSelected(e.RowHandle);

            DrawCheckBox(e.Graphics, r, select);

            e.Handled = true;
        }

        protected virtual void view_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e)
        {
            if (e.Column == CheckMarkColumn)
            {
                if (e.IsGetData)
                {
                    e.Value = IsRowSelected(View.GetRowHandle(e.ListSourceRowIndex));
                }
                else
                {
                    SelectRow(View.GetRowHandle(e.ListSourceRowIndex), (bool)e.Value);
                }
            }
        }

        /// <summary> 行勾选选择改变事件
        /// </summary>
        public event Action<int> RowCheckChanged;

        protected virtual void edit_EditValueChanged(object sender, EventArgs e)
        {
            _view.PostEditor();

        }

        protected virtual void view_RowStyle(object sender, RowStyleEventArgs e)
        {
            if (!IsHighlightSelection)
            {
                return;
            }
            if (IsRowSelected(e.RowHandle))
            {
                //e.Appearance.ForeColor = Color.Blue;
                e.Appearance.Font = new Font(e.Appearance.Font, FontStyle.Bold);

            }
        }

        /// <summary> 应用的GridView
        /// </summary>
        public virtual GridView View
        {
            get
            {
                return _view;
            }
            set
            {
                if (_view != value)
                {
                    Detach();
                    Attach(value);
                }
            }
        }

        /// <summary> Check标记列GridColumn
        /// </summary>
        public virtual GridColumn CheckMarkColumn
        {
            get
            {
                return _column;
            }
        }

        /// <summary> 当前选中的数量
        /// </summary>
        public virtual int SelectedCount
        {
            get
            {
                return Selection.Count;
            }
        }

        /// <summary> 清空选择状态
        /// </summary>
        public virtual void ClearSelection()
        {
            Selection.Clear();
            Invalidate();
        }

        protected virtual void Invalidate()
        {
            _view.CloseEditor();
            _view.BeginUpdate();
            _view.EndUpdate();

        }

        /// <summary> 全选
        /// </summary>
        public virtual void SelectAll()
        {
            Selection.Clear();

            for (int i = 0; i < _view.DataRowCount; i++)
            {
                Selection.Add(_view.GetRow(i));
            }

            Invalidate();
        }

        /// <summary> 设置分组行的选择状态
        /// </summary>
        /// <param name="rowHandle"></param>
        /// <param name="select"></param>
        public void SelectGroup(int rowHandle, int select)
        {
            if (IsGroupRowSelected(rowHandle) == 1 && select == 1)
            {
                return;
            }


            for (int i = 0; i < _view.GetChildRowCount(rowHandle); i++)
            {
                int childRowHandle = _view.GetChildRowHandle(rowHandle, i);
                if (_view.IsGroupRow(childRowHandle))
                {
                    SelectGroup(childRowHandle, select);
                }
                else
                {
                    SelectRow(childRowHandle, select == 1, false);
                }
            }

            Invalidate();
        }

        /// <summary> 设置某行选择状态
        /// </summary>
        /// <param name="rowHandle"></param>
        /// <param name="select"></param>
        public virtual void SelectRow(int rowHandle, bool select)
        {
            SelectRow(rowHandle, select, true);
        }

        /// <summary>
        /// 是否可以通过用户手动选择。只有在Grid选择列为只读状态下时有效。
        /// </summary>
        public bool CanUserSelect
        {
            get; set;
        }

        protected virtual void SelectRow(int rowHandle, bool select, bool invalidate)
        {
            if (IsRowSelected(rowHandle) == select)
            {
                return;
            }

            if (select)
            {
                Selection.Add(_view.GetRow(rowHandle));
            }
            else
            {
                Selection.Remove(_view.GetRow(rowHandle));
            }
            if (invalidate)
            {
                Invalidate();
            }


            if (RowCheckChanged != null)
            {
                RowCheckChanged.Invoke(rowHandle);
            }
        }

        /// <summary>是否分组行选中
        /// </summary>
        /// <param name="rowHandle"></param>
        /// <returns></returns>
        public virtual int IsGroupRowSelected(int rowHandle)
        {
            var childCount = _view.GetChildRowCount(rowHandle);

            int selectRowCount = 0;

            for (int i = 0; i < childCount; i++)
            {
                int row = _view.GetChildRowHandle(rowHandle, i);
                if (_view.IsGroupRow(row))
                {
                    if (1 == IsGroupRowSelected(row))
                    {
                        selectRowCount++;
                    }
                }
                else
                {
                    if (IsRowSelected(row))
                    {
                        selectRowCount++;
                    }
                }
            }

            if (selectRowCount == 0)
            {
                return 0;
            }
            else if (selectRowCount == childCount)
            {
                return 1;
            }
            else
            {
                return 2;
            }
        }

        /// <summary>是否行被选中
        /// </summary>
        /// <param name="rowHandle"></param>
        /// <returns></returns>
        public virtual bool IsRowSelected(int rowHandle)
        {
            if (_view.IsGroupRow(rowHandle))
            {
                return IsGroupRowSelected(rowHandle) == 1;
            }

            object row = _view.GetRow(rowHandle);

            return Selection.Contains(row); ;
        }


    }
}


DevGridRowSelector.zip

4.07 KB, 下载次数: 122

直接可用源码

评分

参与人数 2赞扬 +2 收起 理由
b46bl2 + 1 赞一个
goodworker + 1 感谢分享

查看全部评分

回复

使用道具 举报

0

精华

0

贡献

18

赞扬

帖子
43
软币
239
在线时间
17 小时
注册时间
2014-4-18
 楼主| 发表于 2015-8-4 10:37:36 | 显示全部楼层
都是静态方法,可以直接使用。
回复

使用道具 举报

0

精华

1

贡献

13

赞扬

帖子
13
软币
125
在线时间
5 小时
注册时间
2013-12-5
发表于 2015-9-15 15:48:50 | 显示全部楼层
Skight 发表于 2015-8-4 10:37
都是静态方法,可以直接使用。

加个bool字段就行
回复

使用道具 举报

0

精华

123

贡献

73

赞扬

帖子
106
软币
266
在线时间
16 小时
注册时间
2015-10-16
发表于 2015-10-21 09:23:46 | 显示全部楼层
不错,共享好!!!
回复

使用道具 举报

0

精华

123

贡献

73

赞扬

帖子
106
软币
266
在线时间
16 小时
注册时间
2015-10-16
发表于 2015-10-28 10:39:21 | 显示全部楼层
不错,学习了
回复

使用道具 举报

Archiver|手机版|小黑屋|开发者网 ( 苏ICP备08004430号-2 )
版权所有:南京韵文教育信息咨询有限公司

GMT+8, 2024-6-26 16:27

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表