DataGridView单元格字符超长,ToolTip冒泡提醒功能,可控制宽度和持续显示时间

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;

/*
 * Bob 2012-06-25 写
 * 自定义原因:DataGridView单元格默认ToolTip冒泡提醒无法控制其宽度和显示时间的,如果单元格字符超长,则ToolTip冒泡也会拉的很长,影响美观(真不知道有没有,所以自己写了一个)
 * 注意:BindGridView属性(必选属性)不能为空
 * 调用很简单:本来是写的一个类,但是后来干脆写成一个组件,使用更方便,托到窗体上,选择BindGridView属性和OwnerForm属性即可
 * 说明:还有什么其他需求,可以自己扩展
 * 
 * 关键属性:
 * BindGridView属性 --> 绑定一个DataGridView控件
 * OwnerForm属性 --> 绑定一个Form(即当前控件拖放窗体),主要(Duration = -1)时,当窗体失去焦点,隐藏ToolTip冒泡
 * Duration属性 --> 冒泡持续时间,单位毫秒
 * DisColumns属性 --> 指定需要冒泡的列,默认全部都显示(当文字超过单元格宽度时),注意是列的Name
 * Width、MinWidth、MaxWidth --> 设置冒泡宽度
 * 
 * Bug说明: 
 * 1、当单元格全部为数字、字母、数字字母混合则无法换行
 * 2、当前DataGridView工作区域,DataGridView最后一行,鼠标从单元格下面移出,ToolTip不隐藏,所以有了OwnerForm属性
 */

namespace ProjectTest
{
    /// 
    /// DataGridView显示自定义ToolTip冒泡
    ///  Bob 2012-06-25 写
    /// 
    public class DataGridViewCellToolTip : System.ComponentModel.Component
    {
        ToolTipEx tooltip = null;
        DataGridView dgvList = null;
        Graphics graphics = null;
        int CurrentRowIndex = -1;
        int CurrentColIndex = -1;
        int minWidth = -1;   //显示最小宽度
        int maxWidth = -1;
        int currentWidth = -1;
        string[] colnames = null;       //要显示ToolTip提醒的列
        private Form ownerForm = null;
        int duration = -1;   //持续显示时间
        #region 构造方法


        /// 
        /// DataGridView显示自定义ToolTip冒泡
        /// 
        public DataGridViewCellToolTip(DataGridView dgv)
        {
            InstallToolTip();
            this.OwnerForm = null;
            this.BindGridView = dgv;
            this.colnames = new string[0];
        }

        /// 
        /// DataGridView显示自定义ToolTip冒泡
        /// 
        public DataGridViewCellToolTip()
        {
            InstallToolTip();
        }

        /// 
        /// DataGridView显示自定义ToolTip冒泡
        /// 
        /// 要绑定的DataGridView控件
        public DataGridViewCellToolTip(Form ownerform, DataGridView dgv)
        {
            InstallToolTip();
            this.OwnerForm = ownerform;
            this.BindGridView = dgv;
            this.colnames = new string[0];
        }

        /// 
        /// DataGridView显示自定义ToolTip冒泡
        /// 
        /// 要绑定的DataGridView控件
        /// 要冒泡列(为空或者Length等于0则所有列显示)
        public DataGridViewCellToolTip(Form ownerform, DataGridView dgv, string[] columns)
        {
            InstallToolTip();
            this.OwnerForm = ownerform;
            this.BindGridView = dgv;
            this.colnames = columns;
        }


        #endregion

        #region 属性

        /// 
        /// 绑定DataGridView控件
        /// 
        [DefaultValue(null)]
        [Description("绑定DataGridView对象【必填项】")]
        public DataGridView BindGridView
        {
            get { return dgvList; }
            set
            {
                UninstallDgvEvents();
                dgvList = value;
                InstallDgvEvents();
            }
        }

        /// 
        /// 所属窗体
        /// 
        [Description("所属窗体,有利于弹出的冒泡隐藏【建议填写】")]
        public Form OwnerForm
        {
            get { return ownerForm; }
            set
            {
                UninstallFormDeactivate(ownerForm);
                ownerForm = value;
                InstallFormDeactivate(value);
            }
        }

        /// 
        /// 要显示冒泡提醒的列名名字集合
        /// 
        [Description("要显示冒泡提醒的列名名字集合")]
        [DefaultValue(null)]
        public string[] DisColumns
        {
            get { return colnames; }
            set { colnames = value; }
        }

        /// 
        /// ToolTip显示最小宽度
        /// 
        [DefaultValue(-1)]
        public int MinWidth
        {
            get { return minWidth; }
            set
            {
                if (value < -1)
                {
                    throw new Exception("输入参数错误,不能小于-1");
                }
                if (value > maxWidth && maxWidth > -1)
                {
                    minWidth = maxWidth;
                }
                else
                {
                    minWidth = value;
                }

                if (currentWidth > -1 && minWidth > currentWidth)
                {
                    currentWidth = minWidth;
                }
            }
        }

        /// 
        /// ToolTip显示最小宽度
        /// 
        [DefaultValue(-1)]
        public int MaxWidth
        {
            get { return maxWidth; }
            set
            {
                if (value < -1)
                {
                    throw new Exception("输入参数错误,不能小于-1");
                }
                maxWidth = value;
                if (value > -1 && value < minWidth)
                {
                    minWidth = value;
                }

                if (value > -1 && value < currentWidth)
                {
                    currentWidth = value;
                }
            }
        }

        [DefaultValue(-1)]
        [Description("冒泡宽度,如果为-1,则按DataGridView的列宽计算")]
        public int Width
        {
            get { return currentWidth; }
            set
            {
                if (value < -1)
                {
                    throw new Exception("输入参数错误,不能小于-1");
                }
                if (value < minWidth && value > -1)
                {
                    currentWidth = minWidth;
                }
                else if (value > maxWidth && maxWidth > -1)
                {
                    currentWidth = maxWidth;
                }
                else
                {
                    currentWidth = value;
                }
            }
        }


        [DefaultValue(-1)]
        [Description("持续显示时间,单位毫秒,默认值(-1)则一直显示")]
        public int Duration 
        {
            get { return duration; }
            set 
            {
                if (value < -1)
                {
                    throw new Exception("输入参数错误,不能小于-1");
                }
                duration = value; 
            }
        }

        /// 
        /// 对外公开ToolTip对象[只读]
        /// 
        //public ToolTipEx ToolTipControl
        //{
        //    get { return tooltip; }
        //}
        #endregion

        #region 方法
        private void InstallDgvEvents()
        {
            if (dgvList == null)
            {
                throw new Exception("DataGridView对象不能为空!");
            }
            graphics = dgvList.CreateGraphics();
            dgvList.ShowCellToolTips = false;
            dgvList.CellMouseEnter += new DataGridViewCellEventHandler(DgvCellToolTip_CME);
            dgvList.MouseDown += new MouseEventHandler(DgvCellToolTip_MD);
        }

        private void UninstallDgvEvents()
        {
            if (dgvList != null)
            {
                try
                {
                    dgvList.CellMouseEnter -= DgvCellToolTip_CME;
                    dgvList.MouseDown -= DgvCellToolTip_MD;
                }
                catch { }
            }
        }

        private void InstallToolTip()
        {
            if (tooltip == null)
            {
                tooltip = new ToolTipEx(this);
                //tooltip.ToolTipIcon = ToolTipIcon.Info;
                //tooltip.ToolTipTitle = "Test";
                tooltip.Popup += new PopupEventHandler(tooltip_Popup);
            }
        }

        /// 
        /// 窗体失去焦点 ToolTip隐藏
        /// 
        /// 
        private void InstallFormDeactivate(Form form)
        {
            if (form != null)
            {
                form.Deactivate += new EventHandler(OF_DActive);
                InstallFormDeactivate(form.ParentForm);
            }
        }

        private void UninstallFormDeactivate(Form form)
        {
            if (form != null)
            {
                form.Deactivate -= OF_DActive;
                InstallFormDeactivate(form.ParentForm);
            }
        }

        private void ResetIndex()
        {
            CurrentRowIndex = CurrentColIndex = -1;
        }
        #endregion

        #region 事件绑定方法
        private void OF_DActive(object sender, EventArgs e)
        {
            if (!dgvList.IsDisposed)
            {
                tooltip.Hide(dgvList);
            }
        }

        /// 
        /// 显示前 控制Size
        /// 
        /// 
        /// 
        private void tooltip_Popup(object sender, PopupEventArgs e)
        {
            ToolTipEx tp = sender as ToolTipEx;
            if (tp != null)
            {
                int width = currentWidth;
                if (CurrentColIndex > -1 && currentWidth == -1)
                {
                    width = dgvList.Columns[CurrentColIndex].Width;
                }
                if (width < minWidth)
                {
                    width = minWidth;
                }
                else if (width > maxWidth && maxWidth > -1)
                {
                    width = maxWidth;
                }
                Size size = this.MeasureString(graphics, tp.ToolTipText, dgvList.DefaultCellStyle.Font, width);
                e.ToolTipSize = new Size(width, size.Height + 6);
            }
        }

        private void DgvCellToolTip_CME(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex > -1 && e.RowIndex > -1)
            {
                //单元格没有发送改变则不需要显示,防止闪烁
                if (CurrentRowIndex != e.RowIndex || CurrentColIndex != e.ColumnIndex)
                {
                    CurrentRowIndex = e.RowIndex;
                    CurrentColIndex = e.ColumnIndex;
                    string colname = dgvList.Columns[e.ColumnIndex].Name;
                    //string existname = colnames.FirstOrDefault(n => n.Equals(colname));  //是否存在名字
                    if (IsDisplayToolTip(colname))
                    {
                        DataGridViewCell cell = dgvList.Rows[e.RowIndex].Cells[e.ColumnIndex];
                        if (cell.Value != null)
                        {
                            string cellvalue = cell.Value.ToString();
                            //计算文字显示Size
                            Size size = this.MeasureString(graphics, cellvalue, dgvList.DefaultCellStyle.Font);
                            int width = dgvList.Columns[e.ColumnIndex].Width;
                            //文字宽度大于列宽
                            if (size.Width >= width)
                            {
                                Point cellPoint = dgvList.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false).Location;
                                tooltip.Show(cellvalue, dgvList, cellPoint.X, cellPoint.Y + dgvList.Rows[e.RowIndex].Height, duration);
                                return;
                            }
                        }
                    }

                }
                else
                    return;  //相同单元格返回,不做任何操作,否则当ToolTip覆盖单元格时,鼠标放到ToolTIp上会闪烁(不断的隐藏和显示)
            }
            tooltip.Hide(dgvList);
        }

        private bool IsDisplayToolTip(string colname)
        {
            bool ret = true;
            if (colnames != null && colnames.Length > 0)
            {
                string existname = colnames.FirstOrDefault(n => n.Equals(colname));  //是否存在名字
                if (existname == null)
                {
                    ret = false;
                }
            }
            return ret;
        }

        private void DgvCellToolTip_MD(object sender, MouseEventArgs e)
        {
            tooltip.Hide(dgvList);
        }
        #endregion

        #region 获取文本高度
        protected Size MeasureString(Graphics g, String content, Font font, int width)
        {
            //首先得到每一行文本的标准高度
            SizeF sizef = g.MeasureString(content, font, width);
            Size size = Size.Round(sizef);
            return size;
        }

        protected Size MeasureString(Graphics g, String content, Font font)
        {
            //首先得到每一行文本的标准高度
            SizeF sizef = g.MeasureString(content, font);
            Size size = Size.Round(sizef);
            return size;
        }
        #endregion

        #region 自定义ToolTip对象
        /// 
        /// Bob 2012-06-25 重写ToolTip组件
        /// 
        class ToolTipEx : ToolTip
        {
            string _ToolTipText;
            int _defaultduration = -1;
            DataGridViewCellToolTip _DGVToolTip;

            public ToolTipEx()
                : base()
            {
                _ToolTipText = String.Empty;
            }

            public ToolTipEx(DataGridViewCellToolTip dgvtooltip)
                : base()
            {
                _DGVToolTip = dgvtooltip;
                _ToolTipText = String.Empty;
            }

            public ToolTipEx(System.ComponentModel.IContainer container)
                : base(container)
            {
                _ToolTipText = String.Empty;
            }

            public ToolTipEx(DataGridViewCellToolTip dgvtooltip, System.ComponentModel.IContainer container)
                : base(container)
            {
                _DGVToolTip = dgvtooltip;
                _ToolTipText = String.Empty;
            }

            public string ToolTipText
            {
                get { return _ToolTipText; }
            }

            public new void SetToolTip(Control control, string caption)
            {
                _ToolTipText = caption;
                base.SetToolTip(control, caption);
            }

            public new void Show(string text, IWin32Window window, int x, int y)
            {
                _ToolTipText = text;
                base.Show(text, window, x, y);
            }

            public new void Show(string text, IWin32Window window)
            {
                _ToolTipText = text;
                base.Show(text, window);
            }

            public new void Show(string text, IWin32Window window, int duration)
            {
                _ToolTipText = text;
                if (duration > _defaultduration)
                {
                    base.Show(text, window, duration);
                }
                else
                {
                    base.Show(text, window);
                }
            }

            public new void Show(string text, IWin32Window window, Point point)
            {
                _ToolTipText = text;
                base.Show(text, window, point);
            }

            public new void Show(string text, IWin32Window window, Point point, int duration)
            {
                _ToolTipText = text;
                if (duration > _defaultduration)
                {
                    base.Show(text, window, point, duration);
                }
                else
                {
                    base.Show(text, window, point);
                }
            }

            public new void Show(string text, IWin32Window window, int x, int y, int duration)
            {
                _ToolTipText = text;
                if (duration > _defaultduration)
                {
                    base.Show(text, window, x, y, duration);
                }
                else
                {
                    base.Show(text, window, x, y);
                }
            }

            public new void Hide(IWin32Window window)
            {
                _ToolTipText = String.Empty;
                base.Hide(window);
                if (_DGVToolTip != null)
                {
                    _DGVToolTip.ResetIndex();
                }
            }
        }
        #endregion
    }
}

 

使用: 托到窗体上,选择BindGridView属性(必选)和OwnerForm属性(建议选择)即可

 

本来想上传几张效果图的,不知道怎么了我没有上次图片的权限了

你可能感兴趣的:(最近新发现)