SunnyUI/SunnyUI/Controls/UIToolTip.cs

301 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/******************************************************************************
* SunnyUI 开源控件库、工具类库、扩展类库、多页面开发框架。
* CopyRight (C) 2012-2022 ShenYongHua(沈永华).
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI.dll can be used for free under the GPL-3.0 license.
* If you use this code, please keep this note.
* 如果您使用此代码,请保留此说明。
******************************************************************************
* 文件名称: UIToolTip.cs
* 文件说明: 提示
* 当前版本: V3.1
* 创建日期: 2020-07-21
*
* 2020-07-21: V2.2.6 增加控件
* 2020-07-25: V2.2.6 更新绘制
* 2021-08-16: V3.0.6 增加ToolTip接口解决类似UITextBox这类的组合控件无法显示ToolTip的问题
* 2021-12-09: V3.0.9 修复默认显示
******************************************************************************/
using System;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace Sunny.UI
{
[ProvideProperty("ToolTip", typeof(Control))]
[DefaultEvent("Popup")]
[ToolboxItemFilter("System.Windows.Forms")]
public class UIToolTip : ToolTip
{
private readonly ConcurrentDictionary<Control, ToolTipControl> ToolTipControls =
new ConcurrentDictionary<Control, ToolTipControl>();
public UIToolTip()
{
InitOwnerDraw();
}
public UIToolTip(IContainer cont)
: base(cont)
{
InitOwnerDraw();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
tmpTitleFont?.Dispose();
tmpFont?.Dispose();
}
[DefaultValue(typeof(Font), "微软雅黑, 9pt"), Description("字体"), Category("SunnyUI")]
public Font Font { get; set; } = new Font("微软雅黑", 9);
[DefaultValue(typeof(Font), "微软雅黑, 12pt"), Description("标题字体"), Category("SunnyUI")]
public Font TitleFont { get; set; } = new Font("微软雅黑", 12);
[DefaultValue(typeof(Color), "239, 239, 239"), Description("边框颜色"), Category("SunnyUI")]
public Color RectColor { get; set; } = UIChartStyles.Dark.ForeColor;
[DefaultValue(true), Description("自动大小"), Category("SunnyUI")]
public bool AutoSize { get; set; } = true;
[DefaultValue(typeof(Size), "100, 70"), Description("不自动缩放时大小"), Category("SunnyUI")]
public Size Size { get; set; } = new Size(100, 70);
public new void SetToolTip(Control control, string caption)
{
base.SetToolTip(control, caption);
if (control is IToolTip toolTip)
{
base.SetToolTip(toolTip.ExToolTipControl(), caption);
}
}
public void SetToolTip(Control control, string caption, string title, int symbol, int symbolSize,
Color symbolColor)
{
if (title == null) title = string.Empty;
if (ToolTipControls.ContainsKey(control))
{
ToolTipControls[control].Title = title;
ToolTipControls[control].ToolTipText = caption;
ToolTipControls[control].Symbol = symbol;
ToolTipControls[control].SymbolSize = symbolSize;
ToolTipControls[control].SymbolColor = symbolColor;
}
else
{
var ctrl = new ToolTipControl()
{
Control = control,
Title = title,
ToolTipText = caption,
Symbol = symbol,
SymbolSize = symbolSize,
SymbolColor = symbolColor
};
ToolTipControls.TryAdd(control, ctrl);
}
if (control is IToolTip toolTip)
{
SetToolTip(toolTip.ExToolTipControl(), caption, title, symbol, symbolSize, symbolColor);
}
base.SetToolTip(control, caption);
}
public void SetToolTip(Control control, string caption, string title)
{
if (title == null) title = string.Empty;
if (ToolTipControls.ContainsKey(control))
{
ToolTipControls[control].Title = title;
ToolTipControls[control].ToolTipText = caption;
}
else
{
var ctrl = new ToolTipControl()
{
Control = control,
Title = title,
ToolTipText = caption
};
ToolTipControls.TryAdd(control, ctrl);
}
if (control is IToolTip toolTip)
{
SetToolTip(toolTip.ExToolTipControl(), caption, title);
}
base.SetToolTip(control, caption);
}
public void RemoveToolTip(Control control)
{
if (ToolTipControls.ContainsKey(control))
{
ToolTipControls.TryRemove(control, out _);
}
if (control is IToolTip toolTip)
{
RemoveToolTip(toolTip.ExToolTipControl());
}
}
private void InitOwnerDraw()
{
OwnerDraw = true;
Draw += ToolTipExDraw;
Popup += UIToolTip_Popup;
BackColor = UIChartStyles.Dark.BackColor;
ForeColor = UIChartStyles.Dark.ForeColor;
RectColor = UIChartStyles.Dark.ForeColor;
}
private void UIToolTip_Popup(object sender, PopupEventArgs e)
{
if (ToolTipControls.ContainsKey(e.AssociatedControl))
{
var tooltip = ToolTipControls[e.AssociatedControl];
if (tooltip.ToolTipText.IsValid())
{
if (!AutoSize)
{
e.ToolTipSize = Size;
}
else
{
int symbolWidth = tooltip.Symbol > 0 ? tooltip.SymbolSize : 0;
SizeF titleSize = new SizeF(0, 0);
if (tooltip.Title.IsValid())
{
titleSize = GDI.MeasureString(tooltip.Title, TempTitleFont);
}
SizeF textSize = GDI.MeasureString(tooltip.ToolTipText, TempFont);
int allWidth = (int)Math.Max(textSize.Width, titleSize.Width) + 10;
if (symbolWidth > 0) allWidth = allWidth + symbolWidth + 5;
int allHeight = titleSize.Height > 0 ?
(int)titleSize.Height + (int)textSize.Height + 15 :
(int)textSize.Height + 10;
e.ToolTipSize = new Size(allWidth, allHeight);
}
}
}
else
{
SizeF sf = GDI.MeasureString(GetToolTip(e.AssociatedControl), TempFont);
e.ToolTipSize = sf.Size().Add(10, 10);
}
}
Font tmpFont;
private Font TempFont
{
get
{
if (tmpFont == null || !tmpFont.Size.EqualsFloat(Font.DPIScaleFontSize()))
{
tmpFont?.Dispose();
tmpFont = Font.DPIScaleFont();
}
return tmpFont;
}
}
Font tmpTitleFont;
private Font TempTitleFont
{
get
{
if (tmpTitleFont == null || !tmpTitleFont.Size.EqualsFloat(TitleFont.DPIScaleFontSize()))
{
tmpTitleFont?.Dispose();
tmpTitleFont = TitleFont.DPIScaleFont();
}
return tmpTitleFont;
}
}
private void ToolTipExDraw(object sender, DrawToolTipEventArgs e)
{
var bounds = new Rectangle(e.Bounds.Left, e.Bounds.Top, e.Bounds.Width - 1, e.Bounds.Height - 1);
e.Graphics.FillRectangle(BackColor, bounds);
e.Graphics.DrawRectangle(RectColor, bounds);
if (ToolTipControls.ContainsKey(e.AssociatedControl))
{
var tooltip = ToolTipControls[e.AssociatedControl];
if (tooltip.Symbol > 0)
{
e.Graphics.DrawFontImage(tooltip.Symbol, tooltip.SymbolSize, tooltip.SymbolColor, new Rectangle(5, 5, tooltip.SymbolSize, tooltip.SymbolSize));
}
int symbolWidth = tooltip.Symbol > 0 ? tooltip.SymbolSize : 0;
SizeF titleSize = new SizeF(0, 0);
if (tooltip.Title.IsValid())
{
if (tooltip.Title.IsValid())
{
titleSize = e.Graphics.MeasureString(tooltip.Title, TempTitleFont);
}
e.Graphics.DrawString(tooltip.Title, TempTitleFont, ForeColor,
tooltip.Symbol > 0 ? tooltip.SymbolSize + 5 : 5, 5);
}
if (titleSize.Height > 0)
{
e.Graphics.DrawLine(ForeColor,
symbolWidth == 0 ? 5 : symbolWidth + 5, 5 + titleSize.Height + 3,
e.Bounds.Width - 5, 5 + titleSize.Height + 3);
}
e.Graphics.DrawString(e.ToolTipText, TempFont, ForeColor,
tooltip.Symbol > 0 ? tooltip.SymbolSize + 5 : 5,
titleSize.Height > 0 ? 10 + titleSize.Height : 5);
}
else
{
e.Graphics.DrawString(e.ToolTipText, TempFont, ForeColor, 5, 5);
}
}
public class ToolTipControl : ISymbol
{
public Control Control { get; set; }
public string Title { get; set; }
public string ToolTipText { get; set; }
public int Symbol { get; set; }
public int SymbolSize { get; set; } = 32;
public Point SymbolOffset { get; set; } = new Point(0, 0);
public Color SymbolColor { get; set; } = UIChartStyles.Dark.ForeColor;
}
}
}