【问题标题】:Why a Panel blinks while removing it and its childs?为什么面板在移除它及其子项时会闪烁?
【发布时间】:2015-06-30 00:06:26
【问题描述】:

我有一个带有自定义控件的表单,UserControls。其中一个控件与其他控件组成:TableLayoutPanelPictureBox(它在另一个UserControl 内)、Label。在视觉上,它们以下列方式描绘:

如图所示,红色矩形是UserControl,橙色矩形是TableLayoutPanel,黄色和绿色椅子是由PictureBoxLabel组成的其他UserControl控件.

椅子(黄色和绿色)是动态绘制的。例如画黄色椅子:

    private void DibujarSillasEconomicas()
    {
        Silla[] cheapChairs = m_avion.GetCheapChairs();
        Silla silla;
        byte fila_silla = 0;
        byte col_silla = 0;
        ControlVisualChair ctlSillaGrafica;

        for(int num_silla = 0; num_silla < cheapChairs.Length; ++num_silla)
        {
            silla = cheapChairs[num_silla];
            ctlSillaGrafica = new ControlSillaGrafica(silla);
            ctlSillaGrafica.Dock = DockStyle.Fill;
            ctlSillaGrafica.BackColor = Color.Black;

            if (num_silla > 0 & num_silla % 6 == 0)
            {
                ++fila_silla;
                col_silla = 0;
            }

            tplSillasEconomicas.Controls.Add(ctlSillaGrafica, col_silla == 3? ++col_silla : col_silla, fila_silla);

            ++col_silla;
        }
    }

这些椅子和黄色的椅子画得正确。想注册乘客时出现问题:

请注意,当我添加乘客时,控件会闪烁。在代码中,当我完成添加乘客时我会执行以下操作:

this.Controls.Remove(ctlAvion); // Removes the actual UserControl (red rectangle)
ctlAvion = new ControlAvion(m_avion); // Creates a new one
ctlAvion.Location = new Point(2, 13);
ctlAvion.Size = new Size(597, 475);
this.Controls.Add(ctlAvion); // Adds the new UserControl to the main controls (a Form).

我怎样才能避免这种眨眼效果?

我尝试了以下 UserControls 方法:

ctlAvion.Invalidate();
ctlAvion.Update();
ctlAvion.Refresh();

但它们不起作用!

提前感谢您的帮助!

编辑:

@Idle_Mind 给出的答案是针对我的问题的,它解决了我重新绘制/绘制我设计的自定义控件的问题。

【问题讨论】:

  • 你的 UI 有点像那架飞机,它需要 8 英里的跑道才能起飞。 Try this 快速修复。
  • 这可能是你要找的东西:stackoverflow.com/questions/487661/…
  • @HansPassant,你知道我如何对 UI 的“重量”进行分析/基准测试吗?

标签: c# .net winforms


【解决方案1】:

在对面板控件进行任何修改之前尝试使用SuspendLayout(),之后调用ResumeLayout()

也让你的控件双缓冲,例如为面板定义这个类并使用它来代替面板

public class PanelEx : Panel
{
    public PanelEx()
    {
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        UpdateStyles();
    }
}

【讨论】:

  • 我按照你的建议做了,但它确实解决了闪烁的效果。我在重新创建UserControl 时放置了ctlAvion.SuspendLayout()ctlAvion.ResumeLayout()。谢谢。
  • 正确:“......但它不能解决闪烁效果。”。抱歉打错字了!
【解决方案2】:

使用 WM_SETREDRAW 关闭更新,更新您的 UI,然后重新打开并刷新表单:

    // ... at Form level ...
    private const int WM_SETREDRAW = 11; 

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);

    // ... some method ...

        SendMessage(this.Handle, WM_SETREDRAW, false, 0); // turn updates off

        this.Controls.Remove(ctlAvion); // Removes the actual UserControl (red rectangle)
        ctlAvion = new ControlAvion(m_avion); // Creates a new one
        ctlAvion.Location = new Point(2, 13);
        ctlAvion.Size = new Size(597, 475);
        this.Controls.Add(ctlAvion); // Adds the new UserControl to the main controls (a Form).

        SendMessage(this.Handle, WM_SETREDRAW, true, 0); // turn updates back on
        this.Invalidate();
        this.Refresh();

【讨论】:

  • 感谢@Idle_Mind。您的明确回答解决了我重新绘制/绘制自定义控件的问题。
【解决方案3】:

应用程序必须重新创建整个 UserControl,因此您可以在按下接受按钮时隐藏您的控件,然后修改该控件,然后再次显示该控件。 在此期间,当您的 UserControl 被隐藏时,您可以显示诸如加载屏幕之类的东西。

【讨论】:

    【解决方案4】:

    闪烁来自在绘制前景之前绘制背景的 OnPaintBackground 事件,它具有闪烁效果。 您可以覆盖 OnPaintBackground 并且什么也不做。并使其成为双缓冲。

    public class FlickerFreePanel : System.Windows.Forms.Panel
    {
        public FlickerFreePanel()
        {
            this.DoubleBuffered = true;
        }
    
        protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e)
        {
            if (this.DesignMode)
            {
                base.OnPaintBackground(e);
            }
    
            // Do nothing
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2010-10-12
      • 2013-05-26
      • 1970-01-01
      • 2014-07-25
      • 1970-01-01
      • 2018-02-23
      • 2019-09-07
      • 1970-01-01
      • 2014-03-27
      相关资源
      最近更新 更多