Отключить рисование полосы прокрутки в System.Windows.Forms.RichTextBox - PullRequest
0 голосов
/ 21 апреля 2010

У меня есть пользовательский элемент управления, унаследованный от RichTextBox. Этот элемент управления имеет возможность «отключить» редактирование форматированного текста. Я достигаю этого, просто устанавливая свойство Rtf для свойства text во время события TextChanged.

вот так выглядит мой код:

        private bool lockTextChanged;
        void RichTextBox_TextChanged(object sender, EventArgs e)
        {
            // prevent StackOverflowException
            if (lockTextChanged) return;

            // remember current position
            int rtbstart = rtb.SelectionStart;
            int len = rtb.SelectionLength;


            // prevent painting                
            rtb.SuspendLayout();

            // set the text property to remove the entire formatting.
            lockTextChanged = true;
            rtb.Text = rtb.Text;
            rtb.Select(rtbstart, len);
            lockTextChanged = false;

            rtb.ResumeLayout(true);
      }

Это сработало хорошо. Однако в большом тексте с примерно 200 строками дрожит элемент управления (вы видите первые строки текста для подмигивания).

Чтобы этого не случилось, я фильтрую WM_PAINT между SuspendLayout () и ResumeLayout ()

    private bool layoutSuspended;
    public new void SuspendLayout()
    {
        layoutSuspended = true;
        base.SuspendLayout();
    }

    public new void ResumeLayout()
    {
        layoutSuspended = false;
        base.ResumeLayout();
    }

    public new void ResumeLayout(bool performLayout)
    {
        layoutSuspended = false;
        base.ResumeLayout(performLayout);
    }

    private const int WM_PAINT = 0x000F;
    protected override void WndProc(ref System.Windows.Forms.Message m)
    {
        if (!(m.Msg == WM_PAINT && layoutSuspended))
            base.WndProc(ref m);

    }

, который добился цели, RichTextBox больше не дрожит.
Вот чего я хотел достичь, кроме одной вещи:
Полоса прокрутки продолжает дрожать каждый раз, когда я набираю текст для своего элемента управления.

Теперь мой вопрос: Кто-нибудь знает, как предотвратить перерисовку полосы прокрутки во время макета Suspend / Resume?

1 Ответ

3 голосов
/ 21 апреля 2010

SuspendLayout () не будет иметь эффекта, внутри RTB нет дочерних элементов управления, которые необходимо упорядочить. В RTB отсутствуют методы Begin / EndUpdate (), которые есть в большинстве элементов управления, хотя и поддерживает его. Он приостанавливает рисование, хотя я не уверен, что он приостанавливает обновления полосы прокрутки Добавьте их следующим образом:

public void BeginUpdate() {
  SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)0, IntPtr.Zero);
}
public void EndUpdate() {
  SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero); 
}

// P/invoke declarations
private const int WM_SETREDRAW = 0xb;
[System.Runtime.InteropServices.DllImport("user32.dll")]
private extern static IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 

Лучший способ запретить пользователю редактировать текст - установить для свойства ReadOnly значение True. Полное удаление полосы прокрутки также возможно путем переопределения CreateParams.

...