0

RichTextBoxから継承したカスタムコントロールがあります。このコントロールには、リッチテキスト編集を「無効にする」機能があります。これは、TextChangedイベント中にRtfプロパティをtextプロパティに設定するだけで実現できます。

これは私のコードがどのように見えるかです:

        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行のような大きなテキストでは、コントロールがジッターします(ウィンクのテキストの最初の行が表示されます)。

これを防ぐために、SuspendLayout()とResumeLayout()の間でWM_PAINTをフィルタリングします。

    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はanymoeをジッターしていません。
それが私が達成したかったことです。ただし、1つだけ例外
があります。コントロールにテキストを入力するたびに、スクロールバーがまだ揺れています。

今私の質問:サスペンド/レジュームレイアウト中にスクロールバーが再描画されないようにする方法を教えてくれる人はいますか?

4

1 に答える 1

3

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 をオーバーライドすることで、スクロールバーを完全に削除することもできます。

于 2010-04-21T12:07:35.913 に答える