无效与更新

22 c# drag-and-drop invalidation winforms

我的代码可以让我在winforms中拖动一个无边界形式,我已经使用了几个月了,这非常有效.

但是,当我第一次给出代码时,他们this.Invalidate();MouseMoveForm 的情况下使用了,而且Form稍微闪烁并且在拖动时很慢.所以,我在活动中取代Invalidate()了,令我惊讶的是,Form现在可以非常流畅地拖动,并且没有任何闪烁.Update()MouseMove

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

谢谢 :)

PS如果我添加代码可能会有更多帮助...现在添加它.

编辑 - 这是代码:


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;
}
Run Code Online (Sandbox Code Playgroud)

Jus*_* R. 39

Invalidate()只需一个区域添加到控件的更新区域.下次收到WM_PAINT时,您宣告无效的区域加上任何其他无效区域将被标记为绘画.当RedrawWindow()被调用时,通常会发布一个WM_PAINT消息给应用程序队列.系统可以自由地做它想要的东西,通常是更紧迫的业务,并尽可能地绘画.

如果你打电话Update(),你会得到GDI +,UpdateWindow()它不会标记重新绘制的区域,而是WM_PAINT直接推送到WNDPROC()绕过应用程序队列.

如果您需要立即刷新控件,请使用Refresh(),这会使区域无效,然后立即调用Update().

  • @AdamPlocher从方法注释中可以看出`Invalidate()`只是将区域标记为需要绘制,但不一定要绘制.`Update()`强制任何当前无效的区域重绘,但不标记任何内容.并且`Refresh()`将两个操作包装在一起,首先将控件的区域标记为无效,然后立即请求更新(重新绘制)区域.**编辑:**http://stackoverflow.com/a/952964/1718702 (4认同)

Mar*_*oth 13

Invalidate将窗口标记为需要刷新(在某些时候).更新在那里,如果我没记错的话

这是一个链接来解释差异比我能够更好