无效与更新

发布于 2024-08-21 23:40:56 字数 1402 浏览 4 评论 0原文

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

但是当我第一次得到代码时,他们在Form的MouseMove事件中使用了this.Invalidate();,并且Form在拖动时有点闪烁并且很慢大约。因此,我在MouseMove事件中将Invalidate()替换为Update(),令我惊讶的是,Form现在可以非常顺利地拖动并且没有任何闪烁。

有人可以向我解释为什么 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;
}

I have code that lets be drag around a borderless form in winforms that I've been using for several months now, which works extremely well.

But when I first was given the code, they used this.Invalidate(); in the MouseMove event of the Form, and the Form flickered a little and was slow when dragging around. So, I replaced Invalidate() with Update() in the MouseMove event and, to my surprise, the Form can now be dragged very smoothly and has no flickering whatsoever.

Can somebody explain to me why Update makes the code work better than Invalidate, even when Invalidate sounds like it's the right one to be using?

Thanks :)

P.S. Maybe it would help more if I added the code... Adding it now.

Edit - Here's the code:


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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

故乡的云 2024-08-28 23:40:56

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

如果调用 Update(),您将获得 GDI+ 的 UpdateWindow(),它不会标记要重绘的区域,而是直接将 WM_PAINT 推送到WNDPROC(),绕过应用程序队列。

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

Invalidate() simply adds a region to the update region of the control. The next time WM_PAINT is received, the area you invalidated plus any other invalidated regions, are marked for painting. When RedrawWindow() is called, that will normally post a WM_PAINT message to the application queue. The system is free to do what it wants with that, usually more pressing business, and paint when it can.

If you call Update(), you get GDI+'s UpdateWindow() which won't mark a region for repainting, but pushes a WM_PAINT directly to WNDPROC(), bypassing the application queue.

If you need an immediate refresh of a control, use Refresh(), which invalidates the region then immediately calls Update().

萌无敌 2024-08-28 23:40:56

无效将窗口标记为需要刷新(在某个时刻)。更新在那里进行,然后如果我没记错的话

这是一个链接< /a> 比我能更好地解释差异

Invalidate marks the window as needing to be refreshed (at some point). Update does it there and then if I remember correctly

Here is a link to explain the difference better than I'd be able to

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文