首页 > 代码库 > 重写DataGridViewColumn

重写DataGridViewColumn

做个项目需要用到DataGridView,这个控件还是挺好用的,但是今天却发现无法实现自己想要的功能。主要是DataGridViewCheckBoxColumn这个列虽然是提供了复选框,但是却未能在复选框的旁边提供文本的显示。在网上搜索了一下,提供的方法很多都是弄两列,然后合并单元格,将两列合并成为了一列。不过我不太喜欢那种方式,于是就自己重写了一下DataGridViewColumn,略显简陋,只实现了最基本的功能,现在拿出来,希望各位能够提一些好的意见和见解。

public class DataGridViewCheckBoxLabelColumn : DataGridViewColumn    {        public DataGridViewCheckBoxLabelColumn()            : base()        {            CellTemplate = new DataGridViewCheckBoxCell();        }        /// <summary>        /// 获取和设置用于创建新单元格的模板        /// </summary>        public override DataGridViewCell CellTemplate        {            get            {                return base.CellTemplate;            }            set            {                if (value != null && !value.GetType().IsAssignableFrom(typeof(DataGridViewCheckBoxCell)))                {                    throw new Exception("这个列里面必须绑定DataGridViewCheckBoxCell");                }                base.CellTemplate = value;            }        }        protected override void OnDataGridViewChanged()        {            var dgv = this.DataGridView;            int count = dgv.Rows.Count;            for (int i = 0; i < count; i++)            {                if (dgv.Rows[i].Cells[Name] is DataGridViewCheckBoxCell)                {                    var cell = dgv.Rows[i].Cells[Name] as DataGridViewCheckBoxCell;                    cell.Text = Text;                }            }            base.OnDataGridViewChanged();        }        /// <summary>        /// 复选框的文本        /// </summary>        public string Text { set; get; }        public override object Clone()        {            DataGridViewCheckBoxLabelColumn col = (DataGridViewCheckBoxLabelColumn)base.Clone();            col.Text = Text;            return col;        }    }    public class DataGridViewCheckBoxCell : DataGridViewCell    {        public DataGridViewCheckBoxCell() : base() { }        /// <summary>        /// 要显示的文本        /// </summary>        public string Text { set; get; }        public override object Clone()        {            DataGridViewCheckBoxCell cell = (DataGridViewCheckBoxCell)base.Clone();            cell.Text = Text;            return cell;        }        /// <summary>        /// 单元格的背景色        /// </summary>        private Color CellBackColor { get { return Selected ? Color.FromArgb(49, 106, 197) : OwningRow.DataGridView.BackgroundColor; } }        /// <summary>        /// 单元格前景色        /// </summary>        private Color CellForeColor { get { return Selected ? Color.White : OwningRow.DataGridView.ForeColor; } }        /// <summary>        /// 单元格边框颜色        /// </summary>        private Color CellBorderColor { get { return Color.FromArgb(172, 168, 153); } }        /// <summary>        /// 钩子的颜色        /// </summary>        private Color HookColor { get { return Color.FromArgb(33, 161, 33); } }        /// <summary>        /// 复选框边框颜色        /// </summary>        private Color CheckBoxBorderColor { get { return Color.FromArgb(28, 81, 128); } }        public delegate void CheckedChangedHandle(object sender, DataGridViewCheckBoxLabelCheckedChangedEventArgs e);        /// <summary>        /// 单选框的选中状态发生变化时        /// </summary>        public event CheckedChangedHandle CheckedChanged;        protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds,            System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState,            object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle,            DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)        {            var cell = new Rectangle(cellBounds.X, cellBounds.Y, cellBounds.Width - 1, cellBounds.Height - 1);            graphics.FillRectangle(new SolidBrush(CellBackColor), cell);            graphics.DrawLine(new Pen(CellBorderColor), new Point(cell.X + cell.Width, cell.Y), new Point(cell.X + cell.Width, cell.Y + cell.Height));            graphics.DrawLine(new Pen(CellBorderColor), new Point(cell.X, cell.Y + cell.Height), new Point(cell.X + cell.Width, cell.Y + cell.Height));            var check = formattedValue.Equals("True") || formattedValue.Equals("true");            var box = new Rectangle(cellBounds.X + 4, cellBounds.Y + (cellBounds.Height - 12) / 2, 12, 12);            graphics.FillRectangle(new SolidBrush(Color.White), box);            graphics.DrawRectangle(new Pen(CheckBoxBorderColor, 1.5f), box);            if (check)            {                graphics.DrawString("", new Font("宋体", 8.0f, FontStyle.Bold), new SolidBrush(HookColor), new PointF(box.X - 2, box.Y + 2));            }            if (!string.IsNullOrEmpty(Text))            {                var s = graphics.MeasureString(Text, OwningRow.DataGridView.Font);                var x = box.X + box.Width + 2;                var y = cellBounds.Y + (cellBounds.Height - s.Height) / 2 + 1;                graphics.DrawString(Text, OwningRow.DataGridView.Font, new SolidBrush(CellForeColor), new PointF(x, y));            }            base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);        }        protected override bool MouseClickUnsharesRow(DataGridViewCellMouseEventArgs e)        {            if (e.Button == MouseButtons.Left)            {                var p = new Point(e.X, e.Y);                var row = this.OwningRow;                var x = 4;                var y = (row.Height - 12) / 2;                var r = new Rectangle(x, y, 12, 12);                if (r.Contains(p))                {                    var check = FormattedValue.Equals("True") || FormattedValue.Equals("true");                    Value = !check;                    this.SetValue(RowIndex, Value);                    if (CheckedChanged != null)                        CheckedChanged(this, new DataGridViewCheckBoxLabelCheckedChangedEventArgs(!check, RowIndex, ColumnIndex));                    RaiseCellValueChanged(new DataGridViewCellEventArgs(ColumnIndex, RowIndex));                }            }            return base.MouseClickUnsharesRow(e);        }    }    public class DataGridViewCheckBoxLabelCheckedChangedEventArgs : EventArgs    {        public DataGridViewCheckBoxLabelCheckedChangedEventArgs() : base() { }        /// <summary>        ///         /// </summary>        /// <param name="check">当前单选框是否被选中</param>        /// <param name="rowIndex">单元格所在行的行号</param>        /// <param name="columnIndex">单元格所在列的列号</param>        public DataGridViewCheckBoxLabelCheckedChangedEventArgs(bool check, int rowIndex, int columnIndex)            : base()        {            Checked = check;            RowIndex = rowIndex;            ColumnIndex = columnIndex;        }        /// <summary>        /// 当前单选框是否被选中        /// </summary>        public bool Checked { set; get; }        /// <summary>        /// 单元格所在行的行号        /// </summary>        public int RowIndex { set; get; }        /// <summary>        /// 单元格所在列的列号        /// </summary>        public int ColumnIndex { set; get; }    }

在使用了重写的列后,就基本实现了复选框的选中变化,并呈现了复选框旁边的文本,效果图如下:

重写DataGridViewColumn