我正在构建将显示切片的自定义控件,例如彩色网格。
我设法做了绘图,滚动和基本逻辑,但我在为每个图块创建工具提示时遇到问题。
每种图块颜色取决于"绑定的数据"那个瓷砖。
我试着描述一下我的想法:
上图显示了我的控制,我在那里绘制了4个方格,当用户悬停我控件的不同部分时,我想显示不同的工具提示。
下面是我的工具提示(小红色矩形),下面是标准的WinForms图表组件
我希望在我的控制中得到这种行为(工具提示无法控制,因此可以正确显示长文本。)
下面是我的控件代码,只有基本功能:
public sealed class UC1 : UserControl
{
private bool _showTooltip;
private string _tooltipText;
private Point _mousePosition;
public UC1()
{
MinimumSize = new Size(100, 100);
Size = new Size(100, 100);
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.FillRectangle(Brushes.LightGoldenrodYellow, 0, 0, Width/2, Height/2);
e.Graphics.FillRectangle(Brushes.LightGray, Width/2, 0, Width, Height/2);
e.Graphics.FillRectangle(Brushes.LightSlateGray, 0, Height/2, Width/2, Height);
e.Graphics.FillRectangle(Brushes.LightSteelBlue, Width/2, Height/2, Width, Height);
using (var p = new Pen(Color.Black, 2))
{
e.Graphics.DrawLine(p, Width/2, 0, Width/2, Height);
e.Graphics.DrawLine(p, 0, Height/2, Width, Height/2);
}
if (_showTooltip)
{
SizeF c = e.Graphics.MeasureString(_tooltipText, DefaultFont);
int width = (int) c.Width;
int height = (int) c.Height;
const int offset = 12;
var x = _mousePosition.X + width + offset > Width ? _mousePosition.X - width : _mousePosition.X + offset;
var y = _mousePosition.Y + height + offset > Height ? _mousePosition.Y - height : _mousePosition.Y + offset;
e.Graphics.FillRectangle(Brushes.Red, x, y, width, height);
e.Graphics.DrawString(_tooltipText, DefaultFont, Brushes.Black, x, y);
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.X > 0 && e.X < Width/2 && e.Y > 0 && e.Y < Height/2)
{
Debug.WriteLine("1,1 square");
_tooltipText = "1,1";
}
else if (e.X > Width/2 && e.X < Width && e.Y > 0 && e.Y < Height/2)
{
Debug.WriteLine("1,2 square");
_tooltipText = "1,2";
}
else if (e.X > 0 && e.X < Width/2 && e.Y > Height/2 && e.Y < Height)
{
Debug.WriteLine("2,1 square");
_tooltipText = "2,1";
}
else if (e.X > Width/2 && e.X < Width && e.Y > Height/2 && e.Y < Height)
{
Debug.WriteLine("2,2 square");
_tooltipText = "2,2";
}
_mousePosition = e.Location;
_showTooltip = true;
Refresh();
}
protected override void OnMouseLeave(EventArgs e)
{
_showTooltip = false;
Refresh();
base.OnMouseLeave(e);
}
}
我发现了类似的问题:How to make a floating (tooltip) control in Windows.Forms?但我想避免创建自定义工具提示,而是使用标准工具提示。
如何在悬停在不同的图块上时显示将更改文本的标准工具提示。我想将所有内容添加到我的用户控件中,因此我不必添加任何代码来托管我的控件。
答案 0 :(得分:1)
为什么要尝试自己绘制工具提示而不是使用系统工具?
只需在UC课程中添加一个
// private bool _showTooltip; ?? probably not needed any more..
private string _tooltipText;
// private Point _mousePosition; ??..
ToolTip ttip = new ToolTip();
并将其设置为:
// _mousePosition = e.Location; ??..
// _showTooltip = true; ??..
ttip.SetToolTip(this, _tooltipText); // use this in the mousemove
Refresh();
当然,现在你可以跳过整个绘画部分..
如果您想控制显示ToolTip
的位置,请使用其中一个ShowToolTip()
重载而不是SetToolTip()
..!
虽然两者仍然存在,但这是结果,越过UC的边界并显示出漂亮的投影......:
如果您确实希望ToolTip
看起来与通常的OwnerDraw
不同,可以将true
设置为Draw
并将其GDI+
事件编码,就像任何其他控件一样使用 Point tipLoc = Point.Empty;
图形方法..
<强>更新强>
存在固有的闪烁问题;有关解释,请参阅Hans' answer here;他的建议#2和其中一个答案很有帮助:
记住鼠标的最后位置并仅在鼠标时设置工具提示 职位变动。
所以我们需要添加最后一个ToolTip位置:
if (tipLoc != e.Location )
{
tipLoc = e.Location;
ttip.SetToolTip(this, _tooltipText);
}
我们在鼠标移动中测试和设置:
.nodes()