博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
开源DataGridView扩展(2) 自定义的Button列
阅读量:4949 次
发布时间:2019-06-11

本文共 5560 字,大约阅读时间需要 18 分钟。

一、 DataGridView自带的Button列的缺点

1. 按钮大小不能控制。

2. 按钮文本要么是统一要么就跟单元格内容一致,不能根据具体内容划分几种类型。

3. 按钮的启用/禁用不容易按照内容来自动绑定。

4. 按钮的显示/隐藏也不容易按照内容自动绑定。

5. 按钮的点击事件不能直接抛出,只能靠捕获CellContentClick事件。

6. 一列不能有多个按钮。

二、 DataGridViewEx中是否解决这些问题

1. 如以上图中所示,使用重绘机制,在定义实现的Button列中的可以实现按钮的大小固定,不随单元格改变。并且在Column中可以设置统一的 

    的按钮大小,但是也可以分别设置每一个按钮的大小,既大小可以不相同。

2. 自定义表格中使用Column中的统一默认文本,同时也提供对每一个单元格中的按钮进行单独的设置,这样就可以结合后面的单元格内容格式化

    器来实现不同类型的内容显示不同的按钮了。

3. 在自定义的Button列中支持单个按钮的启用/禁用、显示/隐藏。这个也可以通过下一讲中的单元格内容格式化器来实现绑定。

4. 在自定义的Button列中单独对按钮的点击事件直接抛出给DataGridVieEx层,由DataGridViewEx的CellButtonClicked事件绑定即可,这样就  

    不用再CellClick中绑定,并且还可能出现点击单元格也响应了事件的问题了,这个事件如上面的第二个图。

5. 对于同一列多个按钮的情况,暂时实现,如果以后又可能再继续要讲。

 

    通过这些,其实我们要掌握一个Buttonlie重绘的一个思想:根据我们的需求,更多的东西应该转向按钮本身而不是这一单元格。

三、 DataGridViewEx中的Button列的实现

    就其实现来说,和上一个CheckBox列差不多,Button列主要扩展了两个类:DataGridViewButtonColumnEx和DataGridViewButtonCellEx,

1. 在DataGridViewButtonColumnEx中将CellTemplate设置为DataGridViewButtonCellEx实例:5

public DataGridViewButtonColumnEx()            : base()        {            this.CellTemplate = new DataGridViewButtonCellEx();        }
2. 在DataGridViewButtonCellEx中定义一些需要有用的属性,主用用于按钮,把属性的用途从Cell转为Button:
private bool m_enabled = true;        [Category("Jonson Design"), Browsable(true), Localizable(true), Description("是否可用")]        public bool Enabled        {            get { return m_enabled; }            set { m_enabled = value; }        }        ///         /// 这里按钮的可见进行重写,原有的是从column中统一设置,        /// 通过此属性可以单独设置是否可见        ///         private bool m_visible = true;        [Category("Jonson Design"), Browsable(true), Localizable(true), Description("是否可见")]        public new bool Visible        {            get { return m_visible; }            set { m_visible = value; }        }        ///         /// 如果按钮文本没有单独设置的话,将使用column中设置的文本        ///         private string m_text = string.Empty;        [Category("Jonson Design"), Browsable(true), Localizable(true), Description("按钮文本")]        public string Text        {            get            {                if (string.IsNullOrEmpty(m_text))                    m_text = this.OwningColumnEx.ButtonText;                return m_text;            }            set            {                m_text = value;            }        }
 
3. 针对按钮在鼠标的不同作用下显示不同样式进行处理,要处理这些鼠标的事件:
protected override void OnMouseMove(DataGridViewCellMouseEventArgs e)        {            base.OnMouseMove(e);            if (IsInRegion(e.Location, e.ColumnIndex, e.RowIndex))            {                this.m_curBtnState = PushButtonState.Hot;            }            else            {                this.m_curBtnState = PushButtonState.Normal;            }            this.DataGridView.InvalidateCell(this);        }        protected override void OnMouseLeave(int rowIndex)        {            base.OnMouseLeave(rowIndex);            this.m_curBtnState = PushButtonState.Normal;            this.DataGridView.InvalidateCell(this);        }        protected override void OnMouseDown(DataGridViewCellMouseEventArgs e)        {            base.OnMouseDown(e);            if (IsInRegion(e.Location, e.ColumnIndex, e.RowIndex))            {                this.m_curBtnState = PushButtonState.Pressed;            }            else            {                this.m_curBtnState = PushButtonState.Normal;            }            this.DataGridView.InvalidateCell(this);        }

 

 

4. 绘制按钮,在Paint方法中将按钮按照设定的大小、各种属性以及当前的状态进行绘制:

 

protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle
cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)        {            //            // 此段代码主要解决xp下,如果鼠标默认在按钮列上,按钮的默认绘制样式问题            //            if (this.m_firstDraw)            {                this.m_firstDraw = false;                this.m_curBtnState = this.Enabled ? PushButtonState.Normal : PushButtonState.Disabled;            }            // 是否需要重绘单元格的背景颜色            m_brushCellBack = this.DataGridView.SelectedCells.Contains(this) ?                new SolidBrush(cellStyle.SelectionBackColor) : new SolidBrush(cellStyle.BackColor);            graphics.FillRectangle(m_brushCellBack, cellBounds.X, cellBounds.Y, cellBounds.Width, cellBounds.Height);            //计算button的区域            m_buttonRegion = RectangleCommon.GetSmallRectOfRectangle(cellBounds, this.Size, out this.m_absBtnRegion);            //绘制按钮            if (m_enabled)                this.InternalDrawButton(graphics, m_buttonRegion, m_curBtnState, Text);            else                this.InternalDrawButton(graphics, m_buttonRegion, PushButtonState.Disabled, Text);            // 填充单元格的边框            base.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);        }        protected void InternalDrawButton(Graphics graphics, Rectangle bounds, PushButtonState buttonState, string buttonText)        {            //如果是隐藏的,不绘制            if (!m_visible) return;            Color buttonTextColor = SystemColors.ControlText;            if (buttonState == PushButtonState.Disabled)                buttonTextColor = SystemColors.GrayText;            ButtonRenderer.DrawButton(graphics, bounds, buttonState);            if (buttonText != null)                TextRenderer.DrawText(graphics, buttonText, this.DataGridView.Font, bounds, buttonTextColor);        }

四、 Demo程序和开源源码

         上一篇    :

         Demo下载  :

         源码下载   :

 

下一讲  将介绍如何设计一个单元格内容格式化器,轻松实现按内容显示颜色、禁用按钮等。

转载于:https://www.cnblogs.com/gxjiang/archive/2012/04/29/2476439.html

你可能感兴趣的文章
详解ASP.Net 4中的aspnet_regsql.exe
查看>>
python 多进程和多线程的区别
查看>>
hdu1398
查看>>
[android] 网络断开的监听
查看>>
156.Binary Tree Upside Down
查看>>
MongoDB在windows下安装配置
查看>>
Upselling promotion stored procedure
查看>>
mysql编码配置
查看>>
KVM地址翻译流程及EPT页表的建立过程
查看>>
sigar
查看>>
iOS7自定义statusbar和navigationbar的若干问题
查看>>
c++ 网络编程(一)TCP/UDP windows/linux 下入门级socket通信 客户端与服务端交互代码...
查看>>
程序员如何提高影响力:手把手教你塑造个人品牌
查看>>
身份证校验原理和PHP实现
查看>>
[Locked] Wiggle Sort
查看>>
deque
查看>>
计算机
查看>>
Ext JS学习第十三天 Ext基础之 Ext.Element
查看>>
python--迭代器与生成器
查看>>
SQL之case when then用法详解
查看>>