重写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; }
    }

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

时间: 2024-12-23 00:13:56

重写DataGridViewColumn的相关文章

怎么自定义DataGridViewColumn(日期列,C#)

参考:https://msdn.microsoft.com/en-us/library/7tas5c80.aspx 未解决的问题:如果日期要设置为null,怎么办? DataGridView控件提供了多种列类型,使我们可以以多种方式录入和编辑值.如果这些列类型不能满足我们数据录入方式的要求时,则需要创建自己的列类型,其单元格(cells)持有我们选择的控件.自定义列类型需要创建三个类: 1. 创建类,继承DataGridViewColumn 2. 创建类,继承DataGridViewCell 3

java中的重写和重载

重写 在java中有很多的继承,继承下来的有变量.方法.在有一些子类要实现的方法中,方法名.传的参数.返回值跟父类中的方法一样,但具体实现又跟父类的不一样,这时候我们就需要重写父类的方法,就比如我们有一个类叫做Animals,Animals类中有一个叫做Call,然后我们继承Animals又生成了Cat类和Dog类,Cat和Dog也分别有自己特别的叫声,程序如下: 1 class Animals { 2 public void call() { 3 System.out.println("啊啊啊

Cento7+Nginx 之 URL重写

Cento7+Nginx  之  URL重写 我们前一篇文章写了一个Cento7+Nginx 反向代理实现多域名跳转,今天主要介绍一下Cento7+Nginx  之  URL重写, Hostname:A-S.IXMSOFT.COM IP:192.168.5.20 Role:Nginx server 我们首先准备安装Nginx仓库 Yum install http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.

重写js alert

Window.prototype.alert = function(){ //创建一个大盒子 var box = document.createElement("div"); //创建一个关闭按钮 var button = document.createElement("button"); //定义一个对象保存样式 var boxName = { width:"500px", height:"180px", backgroun

二:理解ASP.NET的运行机制(例:基于HttpHandler的URL重写)

url重写就是把一些类似article.aspx?id=28的路径重写成 article/28/这样的路径 当用户访问article/28/的时候我们通过asp.net把这个请求重定向到article.aspx?id=28路径有两种方法可以做这件事情 一:基于HttpModule的方案这个方案有有缺点,具体缺点以后再谈我曾写过一篇文章<不用组件的url重写(适用于较大型项目) >就是按这个模式写的 二:基于HttpHandler的方案我们这个例子就是按这个方案做的我们接下来就按这种方式做这个例

在IIS 中如何配置URL Rewrite,并且利用出站规则保持被重写的Cookie的域

Url Rewrite配置 xx.aa.com/bb/test1.aspx 会重写到 bb.aa.com/test1.aspx 具体怎么配置入站 出站规则 结果:

PHP 方法重写override 与 抽象方法的实现之间的关系

重写由final关键字决定,但受父类的访问权限限制 实现基于继承,所以实现父类的抽象方法必须可访问到,父类抽象方法不可为private 1.父类某方法能否被子类重写与此方法的访问级别无关 public protected private对某方法内否被重写没有影响,能否被重写要看此方法是否被final修饰(final类不可被继承,final方法不可被重写) 2.但重写方法要受到访问级别的限制,即访问权限不可提升规定 (不仅仅是PHP,其他面向对象语言依然适用),访问权限只可以降低,不可以提升. 3

项目搭建系列之四:SpringMVC框架下使用UrlRewrite实现地址重写

简单记录一下UrlRewrite实现地址重写功能. 1.pom.xml 在pom.xml增加配置UrlRewrite jar <!-- URL Rewrite --> <dependency> <groupId>org.tuckey</groupId> <artifactId>urlrewritefilter</artifactId> <version>4.0.4</version> </dependen

重写equals和hashCode方法的示例

如果一个类有自己特有的"逻辑相等",且需要以此进行比较时,那么就需要重写equals方法. 在Object的规范中,重写equals方法有下面几条通用约定: 自反性. x.equals(x) == true 对称性.if   y.equals(x) == true , then  x.equals(y) == true 传递性.if   x.equals(y) == true y.equals(x) == true , then x.equals(z) == true 一致性.如果比较