我整天都在研究这个问题,(继续笑笑),我也没有看到任何解决闪烁控制的古老形式问题的方法。我的控件是TabControl,我正在使用DrawMode OwnerDrawFixed。我挂钩了以下事件。总之,我正在创建一个TabControl,可以关闭" X" 12x12 png资源的按钮。关闭按钮都是灰色的,但是如果我鼠标悬停在一个上,它应该使用不同的图像(红色X)。
MouseDown:循环显示所有TabPages并检查我是否点击了我正在绘制关闭按钮图像的矩形。
MouseLeave:当我离开TabControl以确保所有内容都正确绘制时我需要无效
MouseMove:循环显示所有TabPages并检查我是否已将鼠标悬停在我正在绘制关闭按钮图像的矩形上。如果我将鼠标移除,那么我保存标签页索引,以便我的画颜料可以更改用于关闭按钮的图像。
DrawItem:这里我只是绘制图像
我测试的东西但没有运气......
创建我自己的继承TabControl的TabControl类,并在构造函数中使用SetStyles for OptimizedDoubleBuffering为true(我将其他建议标志设置为true)
我试过覆盖CreateParams所以我可以或者这个值... createParams.ExStyle | = 0x00000020; (我不知道这是做什么的,但是读了一个建议这样做的用户。
设置表单DoubleBuffered(什么都不做)
无论如何,我无法思考该怎么做,而且我已经读了一段时间。
这是我所有活动的代码。我只想在我的标签上设置关闭按钮,当我将鼠标悬停在它们上时会突出显示。感谢。
private int mousedOver = -1;//indicates which close button is moused over
private void tabControl_DrawItem(object sender, DrawItemEventArgs e)
{
e.Graphics.DrawImage(e.Index == mousedOver ? Resources.redX : Resources.grayX, e.Bounds.Right - 15, e.Bounds.Top + 4);
}
private void tabControl_MouseDown(object sender, MouseEventArgs e)
{
TabControl tc = sender as TabControl;
if (tc.TabCount == 1) return;
for (int i = 0; i < tc.TabPages.Count; i++)
{
Rectangle r = tc.GetTabRect(i);
Rectangle closeButton = new Rectangle(r.Right - 15, r.Top + 4, 12, 12);
if (closeButton.Contains(e.Location))
{
TabPage tp = tc.TabPages[i];
tc.TabPages.Remove(tp);
tp.Dispose();
break;
}
}
}
private void tabControl_MouseMove(object sender, MouseEventArgs e)
{
TabControl tc = sender as TabControl;
for (int i = 0; i < tc.TabPages.Count; i++)
{
Rectangle r = tc.GetTabRect(i);
Rectangle closeButton = new Rectangle(r.Right - 15, r.Top + 4, 12, 12);
if (closeButton.Contains(e.Location))
{
mousedOver = i;
tc.Invalidate();
return;
}
}
mousedOver = -1;
tc.Invalidate();
}
private void tabControl_MouseLeave(object sender, EventArgs e)
{
TabControl tc = sender as TabControl;
mousedOver = -1;
tc.Invalidate();
}
答案 0 :(得分:1)
看起来你经常无效。尝试过滤它,以便只在需要重新绘制控件时使其无效:
private void tabControl_MouseMove(object sender, MouseEventArgs e) {
TabControl tc = sender as TabControl;
for (int i = 0; i < tc.TabPages.Count; i++) {
Rectangle r = tc.GetTabRect(i);
Rectangle closeButton = new Rectangle(r.Right - 15, r.Top + 4, 12, 12);
if (closeButton.Contains(e.Location)) {
if (mousedOver != i) {
mousedOver = i;
tc.Invalidate(r);
}
} else if (mousedOver == i) {
int oldMouse = mousedOver;
mousedOver = -1;
tc.Invalidate(tc.GetTabRect(oldMouse));
}
}
}
我会保持CreateParams覆盖,但作为本机Windows控件,你可能永远不会完全消除一些闪烁。
答案 1 :(得分:0)
您也可以尝试通过
设置控件的DoubleBuffered属性Control.DoubleBuffered = true;
我知道这适用于DataGridViews,ListViews,Forms和Panel。
可在MSDN上找到文档。