我正在使用this answer中的代码,并且运行良好!
但是,现在我需要添加一个悬停图像,因为没有一个图像会感到很沉闷。
我已经绘制了图像,我只需要在悬停时更改图像,然后在停止悬停时将其更改回即可。
Invalidate()
有一些建议,但我不太了解如何使用它。
我尝试将以下代码放入MouseMove
的{{1}}事件中,
TabControl
但这似乎也不起作用。
变量for (var i = 0; i < this.tabControl1.TabPages.Count; i++)
{
var tabRect = this.tabControl1.GetTabRect(i);
tabRect.Inflate(-2, -2);
var imageRect = new Rectangle(tabRect.Right - CloseImage.Width,
tabRect.Top + (tabRect.Height - CloseImage.Height) / 2,
CloseImage.Width,
CloseImage.Height);
if (imageRect.Contains(e.Location))
{
isHover = true;
isNormal = false;
Invalidate(tabRect);
}
else
{
isNormal = true;
isHover = false;
Invalidate(tabRect);
}
}
和isNormal
已经在较早的代码中创建,并且在isHover
事件内部,我具有:
DrawItem
但是它仍然无法正常工作。
如果我的问题不清楚,我很抱歉:)
答案 0 :(得分:1)
您的代码中存在几个问题:
CloseImage
相同,即使将鼠标悬停在一个选项卡上时,其绘制方式也不同于其他选项卡。 解决方案:将每个TabPage
的图片存储在其Tag
属性中。isHover
和isNormal
字段。这和 1 一样。 (顺便说一句,没有理由使用两个标志,一个标志就足够了,它更简单且更不容易出错)。isHover = false;
,isNormal = true;
进行绘图后将其重置,但是可以通过其他触发器再次重新绘制表单,并且图像将恢复正常。Invalidate
形式的tabRect
方法,但是tabRect
相对于TabControl
的坐标。 解决方案:使用tabControl1.Invalidate(tabRect)
。以下是对代码进行的一些更改(带有注释),它们可以正常工作:
Image NormalImage = Properties.Resources.normalImage;
Image HoverImage = Properties.Resources.hoverImage;
private void Form1_Load(object sender, EventArgs e)
{
this.tabControl1.DrawMode = System.Windows.Forms.TabDrawMode.OwnerDrawFixed;
tabControl1.DrawItem += TabControl1_DrawItem;
tabControl1.MouseClick += TabControl1_MouseClick;
this.tabControl1.Padding = new Point(10, 3);
this.tabControl1.MouseMove += TabControl1_MouseMove;
// Store the image for each tab page in its Tag
foreach (TabPage tabPage in tabControl1.TabPages)
{
tabPage.Tag = NormalImage;
}
}
private void TabControl1_MouseMove(object sender, MouseEventArgs e)
{
// Select the image to draw for each tab
for (var i = 0; i < this.tabControl1.TabPages.Count; i++)
{
var tabRect = this.tabControl1.GetTabRect(i);
tabRect.Inflate(-2, -2);
var imageRect = new Rectangle(tabRect.Right - NormalImage.Width,
tabRect.Top + (tabRect.Height - NormalImage.Height) / 2,
NormalImage.Width,
NormalImage.Height);
// Find what image needs to be drawn
Image imageToDraw = imageRect.Contains(e.Location) ? HoverImage : NormalImage;
// Update the image and invalidate only if the image has change to avoid flicker
// Invalidate using the tabControl1
if(tabControl1.TabPages[i].Tag != imageToDraw)
{
tabControl1.TabPages[i].Tag = imageToDraw;
tabControl1.Invalidate(tabRect);
}
}
}
private void TabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
try
{
// Get the image to draw from the TabPages Tag propery.
Image image = (Image)this.tabControl1.TabPages[e.Index].Tag;
var tabRect = this.tabControl1.GetTabRect(e.Index);
tabRect.Inflate(-2, -2);
var imageRect = new Rectangle(tabRect.Right - image.Width,
tabRect.Top + (tabRect.Height - image.Height) / 2,
image.Width,
image.Height);
var sf = new StringFormat(StringFormat.GenericDefault);
if (this.tabControl1.RightToLeft == System.Windows.Forms.RightToLeft.Yes &&
this.tabControl1.RightToLeftLayout == true)
{
tabRect = GetRTLCoordinates(this.tabControl1.ClientRectangle, tabRect);
imageRect = GetRTLCoordinates(this.tabControl1.ClientRectangle, imageRect);
sf.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
}
e.Graphics.DrawString(this.tabControl1.TabPages[e.Index].Text,
this.Font, Brushes.Black, tabRect, sf);
e.Graphics.DrawImage(image, imageRect.Location);
}
catch (Exception) { }
}
我希望添加一个tabControl1.MouseLeave
事件以将所有TabPage
标签重置为NormalImage
。