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 { /// <summary> /// DataGridView显示自定义ToolTip冒泡 /// Bob 2012-06-25 写 /// </summary> 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 构造方法 /// <summary> /// DataGridView显示自定义ToolTip冒泡 /// </summary> public DataGridViewCellToolTip(DataGridView dgv) { InstallToolTip(); this.OwnerForm = null; this.BindGridView = dgv; this.colnames = new string[0]; } /// <summary> /// DataGridView显示自定义ToolTip冒泡 /// </summary> public DataGridViewCellToolTip() { InstallToolTip(); } /// <summary> /// DataGridView显示自定义ToolTip冒泡 /// </summary> /// <param name="dgv">要绑定的DataGridView控件</param> public DataGridViewCellToolTip(Form ownerform, DataGridView dgv) { InstallToolTip(); this.OwnerForm = ownerform; this.BindGridView = dgv; this.colnames = new string[0]; } /// <summary> /// DataGridView显示自定义ToolTip冒泡 /// </summary> /// <param name="dgv">要绑定的DataGridView控件</param> /// <param name="columns">要冒泡列(为空或者Length等于0则所有列显示)</param> public DataGridViewCellToolTip(Form ownerform, DataGridView dgv, string[] columns) { InstallToolTip(); this.OwnerForm = ownerform; this.BindGridView = dgv; this.colnames = columns; } #endregion #region 属性 /// <summary> /// 绑定DataGridView控件 /// </summary> [DefaultValue(null)] [Description("绑定DataGridView对象【必填项】")] public DataGridView BindGridView { get { return dgvList; } set { UninstallDgvEvents(); dgvList = value; InstallDgvEvents(); } } /// <summary> /// 所属窗体 /// </summary> [Description("所属窗体,有利于弹出的冒泡隐藏【建议填写】")] public Form OwnerForm { get { return ownerForm; } set { UninstallFormDeactivate(ownerForm); ownerForm = value; InstallFormDeactivate(value); } } /// <summary> /// 要显示冒泡提醒的列名名字集合 /// </summary> [Description("要显示冒泡提醒的列名名字集合")] [DefaultValue(null)] public string[] DisColumns { get { return colnames; } set { colnames = value; } } /// <summary> /// ToolTip显示最小宽度 /// </summary> [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; } } } /// <summary> /// ToolTip显示最小宽度 /// </summary> [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; } } /// <summary> /// 对外公开ToolTip对象[只读] /// </summary> //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); } } /// <summary> /// 窗体失去焦点 ToolTip隐藏 /// </summary> /// <param name="form"></param> 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); } } /// <summary> /// 显示前 控制Size /// </summary> /// <param name="sender"></param> /// <param name="e"></param> 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对象 /// <summary> /// Bob 2012-06-25 重写ToolTip组件 /// </summary> 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属性(建议选择)即可
本来想上传几张效果图的,不知道怎么了我没有上次图片的权限了