【问题标题】:How do you prevent a RichTextBox from refreshing its display?如何防止 RichTextBox 刷新其显示?
【发布时间】:2008-10-10 17:42:11
【问题描述】:

我有一个 RichTextBox,我需要经常更新 Text 属性,但是当我这样做时,RichTextBox 会令人讨厌地“闪烁”,因为它会在整个方法调用过程中刷新所有内容。

我希望找到一种简单的方法来暂时抑制屏幕刷新,直到我的方法完成,但我在网上找到的唯一方法是重写 WndProc 方法。我采用了这种方法,但有一些困难和副作用,而且它也使调试更加困难。似乎必须有更好的方法来做到这一点。有人可以指出更好的解决方案吗?

【问题讨论】:

    标签: c# winforms richtextbox


    【解决方案1】:

    这是完整且有效的示例:

        private const int WM_USER = 0x0400;
        private const int EM_SETEVENTMASK = (WM_USER + 69);
        private const int WM_SETREDRAW = 0x0b;
        private IntPtr OldEventMask;       
    
        [DllImport("user32.dll", CharSet=CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
    
        public void BeginUpdate()
        {
            SendMessage(this.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
            OldEventMask = (IntPtr)SendMessage(this.Handle, EM_SETEVENTMASK, IntPtr.Zero, IntPtr.Zero);
        }       
    
        public void EndUpdate()
        {
            SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
            SendMessage(this.Handle, EM_SETEVENTMASK, IntPtr.Zero, OldEventMask);
        }
    

    【讨论】:

      【解决方案2】:

      我问了最初的问题,最适合我的答案是 BoltBait 将 SendMessage() 与 WM_SETREDRAW 结合使用。它似乎比使用 WndProc 方法具有更少的副作用,并且在我的应用程序中执行的速度是 LockWindowUpdate 的两倍。

      在我扩展的 RichTextBox 类中,我刚刚添加了这两个方法,当我在进行某些处理时需要停止重新绘制时,我会调用它们。如果我想从 RichTextBox 类之外执行此操作,我认为只需将“this”替换为对 RichTextBox 实例的引用即可。

          private void StopRepaint()
          {
              // Stop redrawing:
              SendMessage(this.Handle, WM_SETREDRAW, 0, IntPtr.Zero);
              // Stop sending of events:
              eventMask = SendMessage(this.Handle, EM_GETEVENTMASK, 0, IntPtr.Zero);
          }
      
          private void StartRepaint()
          {
              // turn on events
              SendMessage(this.Handle, EM_SETEVENTMASK, 0, eventMask);
              // turn on redrawing
              SendMessage(this.Handle, WM_SETREDRAW, 1, IntPtr.Zero);
              // this forces a repaint, which for some reason is necessary in some cases.
              this.Invalidate();
          }
      

      【讨论】:

      • 有机会完成代码吗?这几乎不像目前所写的那样可编译。
      • Invalidate() 调用是预期的。我在 MDI 应用程序中使用了一个变体,其中每个 MDI 子窗口都包含一个 RichTextBox。在这种情况下,我必须使用 child.richTextBox.Invalidate(); 使控件无效
      【解决方案3】:

      在这里找到:http://bytes.com/forum/thread276845.html

      我最终通过 SendMessage 发送了一个 WM_SETREDRAW 来禁用然后重新启用 在我完成更新后跟着一个 Invalidate() 。这似乎奏效了。

      我从未尝试过这种方法。我编写了一个带有语法突出显示的 RTB 应用程序,并在 RTB 类中使用了以下内容:

      protected override void WndProc(ref Message m)
      {
          if (m.Msg == paint)
          {
              if (!highlighting)
              {
                  base.WndProc(ref m); // if we decided to paint this control, just call the RichTextBox WndProc
              }
              else
              {
                  m.Result = IntPtr.Zero; // not painting, must set this to IntPtr.Zero if not painting otherwise serious problems.
              }
          }
          else
          {
              base.WndProc(ref m); // message other than paint, just do what you normally do.
          }
      }
      

      希望这会有所帮助。

      【讨论】:

      • WM_SETREDRAW 为我工作。应该和 LockWindowUpdate 一样。
      【解决方案4】:

      您能否将 Text 存储到字符串中,对字符串进行操作,然后在方法结束时将其存储回 Text 属性中?

      【讨论】:

        【解决方案5】:

        我建议查看LockWindowUpdate

        [DllImport("user32.dll", EntryPoint="LockWindowUpdate", SetLastError=true, ExactSpelling=true, CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]

        【讨论】:

        【解决方案6】:

        试试这个:

        myRichTextBox.SuspendLayout();
        DoStuff();
        myRichTextBox.ResumeLayout();
        

        【讨论】:

        • 您可能还需要添加 myRichTextBox.Enabled = false;和后来的 Enabled = true;
        • SuspendLayout() 在这里并没有真正的帮助。
        猜你喜欢
        • 2021-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-25
        • 2020-01-25
        • 2010-10-18
        • 2014-02-14
        • 1970-01-01
        相关资源
        最近更新 更多