无效与更新

问题描述 投票:0回答:2

我有代码可以在 winforms 中拖动无边框表单,我已经使用了几个月了,效果非常好。

但是当我第一次得到代码时,他们在表单的

this.Invalidate();
事件中使用了
MouseMove
,并且表单在拖动时有点闪烁并且很慢。于是,我在
Invalidate()
事件中将
Update()
替换为
MouseMove
,令我惊讶的是,表单现在可以非常平滑地拖动,并且没有任何闪烁。

有人可以向我解释为什么 Update 使代码比 Invalidate 工作得更好,即使 Invalidate 听起来像是正确的使用方式?

谢谢:)

附注如果我添加代码,也许会有更多帮助...现在添加。

编辑 - 这是代码:


private void titlebar_MouseDown(object sender, MouseEventArgs e)
{
    this.IsMouseDown = true;

    this.LastCursorPosition = new Point(e.X, e.Y);

    if (this.BackColor == Color.White)
    {
        this.BackColor = Color.GhostWhite;
        tbox.BackColor = Color.GhostWhite;
        tbox.ForeColor = Color.Black;
    }
    else
    {
        this.BackColor = Color.FromArgb(20, 20, 20);
        tbox.BackColor = Color.FromArgb(20, 20, 20);
        tbox.ForeColor = Color.White;
    }
}

private void titlebar_MouseMove(object sender, MouseEventArgs e)
{
    if (this.IsMouseDown == true)
    {
        //Move the form
        this.Location = new Point(this.Left - (this.LastCursorPosition.X - e.X), this.Top - (this.LastCursorPosition.Y - e.Y));

        // Update works better than Invalidate();.
        Update();
    }
}

private void titlebar_MouseUp(object sender, MouseEventArgs e)
{
    this.IsMouseDown = false;
    this.BackColor = fc;
    tbox.BackColor = fc;
}
c# winforms drag-and-drop invalidation
2个回答
42
投票

Invalidate()
只是将一个区域添加到控件的更新区域。下次收到 WM_PAINT 时,您无效的区域以及任何其他无效区域都将被标记为要绘制。当调用 RedrawWindow() 时,通常会将 WM_PAINT 消息发送到应用程序队列。系统可以自由地做它想做的事,通常是更紧迫的业务,并在可以的时候进行绘制。

如果您调用

Update()

,您将获得 GDI+ 的

UpdateWindow()
,它不会标记要重绘的区域,而是将
WM_PAINT
直接推送到
WNDPROC()
,绕过应用程序队列。

如果您

需要

立即刷新控件,请使用Refresh(),这会使该区域无效,然后立即调用

Update()
    


16
投票

博客文章

Control.Invalidate、Control.Update 和 Control.Refresh 之间有什么区别? 将比我更好地解释这些区别。

© www.soinside.com 2019 - 2024. All rights reserved.