在父级的MouseMove事件中移动标签会导致尾部重绘。
我(错)使用System.Windows.Forms.Label对象来实现
为此,我将标签创建为父控件的成员(顺便说一下。它是一个带鼠标滚轮缩放,平移等的自定义图形控件),将它们添加到父控件列表中,然后将它们移动到MouseMove-父母的事件。为了确保清晰的移动行为,我甚至在分配标签的位置属性时调用Label.Refresh。
void GraphViewMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (lastLocation != e.Location)
{
HasMoved = true;
if (IsPanning && e.Button == MouseButtons.Left)
{
if (isSelecting) PerformSelection(e.Location);
else PerformMove(e.Location,lastLocation);
}
lastLocation = e.Location;
if (Width > 0 && Height > 0)
{
PointD pos = CursorPosition;
// nothing interesting, basically like what is done with the crossHair's below
coordinateToolTip.Locate(lastLocation, pos.X, pos.Y);
crossHairX.Location = new Point(lastLocation.X, 0);
crossHairY.Location = new Point(0, lastLocation.Y);
crossHairX.Refresh();
crossHairY.Refresh();
}
}
}
一切都很好(标签与鼠标光标平行移动)除了当我快速移动鼠标时,标签的几个副本保留在父母的客户区域中一段时间就像一个视觉回声。
也就是说,虽然新位置的标签重绘似乎是立即发生的,但在父母的背景之前似乎只需要一秒钟的时间(一些复杂的图形,完全重绘需要几秒钟,但是在所说的简单鼠标移动过程中肯定没有重新绘制)恢复到最初移动的标签背后的内容。这当然在功能上是无关紧要的,但它看起来很丑陋,因为它给人的印象是代码效率低下。
有没有办法强制(更快)重绘缓存的背景图形?什么决定了控件后面的屏幕内容恢复之前的延迟?
编辑:关于设置DoubleBuffered = true的建议:根据MSDN,默认情况下这应该是真的。事实上,如果我为Label设置它,它没有任何区别。另一方面,将其设置为false会引入预期的额外闪烁。在任何一种情况下,背景的恢复都会延迟,如上所述。
答案 0 :(得分:0)
@Hans Passant:感谢您告诉我们“移动控件时,其父级的OnPaintBackground()方法需要运行以过度绘制控件在其先前位置留下的像素。” < / strong>
对我来说, cp.ExStyle | = 0x02000000; //开启WS_EX_COMPOSITED 无效。 我正在创建可移动的,可调整大小的面板,当我从左向右快速移动它时,它没有显示在右侧,“面板的一半经常消失了”。我这样做了,现在它的工作原理就像我移动Windows窗口时一样。
这是我在面板中继承并继承的MyPanel类中
protected override void OnMove(EventArgs e)
{
this.Parent.Invalidate();
base.OnMove(e);
}
因此,当我用鼠标移动“可移动”面板时,它将使我的案例中的“ Parrent”无效,窗体现在可以正常移动了。