2011-06-28 14 views
6

多くのアプリケーションでは、テキスト編集を頻繁に行うことを期待していますが、アプリケーションを操作する可能性が最も高いテキストを強調表示するという点で、テキストをダブルクリックするとデフォルト以外の動作が行われます。簡単な例として、この文は、異なるアプリケーションで異なる動作をテキスト領域またはテキストボックスをダブルクリックしたときの強調表示の動作を指定しますか?

:私はメモ帳やダブルワードをクリックしてください「サンプル」であることを入力すると

これは、「サンプル」文

です(理想的に言えば、サンプルの 'm'と 'p'の間の単語の中間)、最初の見積もりから2番目の見積もり後のスペースまでのメモ帳が強調表示されます。その文がVisual Studioのコメントにあり、同じ場所をダブルクリックすると、引用符を強調表示せずにサンプルの 'e'にハイライト表示されます。

自分のアプリケーションでこれらのハイライト表示をカスタマイズするにはどうすればよいですか? winformsとWPFは異なるのですか?私はそれをダブルクリックイベントで動作させるために自分のやり方をハックすることができると思うが、もっと優雅な/意図的な解決策がこれ専用にあるのだろうか?

+0

私の回答はまったく役に立たなかったのですか、この質問は死んだ質問ですか? – Skintkingle

+0

あなたの答えは私自身の種類のものを転がしたいと思ったら私がやることです。私は、ダブルクリックでハイライトするテキストをカスタム条件にするために、イベント駆動型、コンテキスト依存型の方法に対応したアプローチを探していました。明らかにこれを行う方法はありません。 –

答えて

2

はい、DoubleClickイベントを使用すると、kludgyが表示されているように表示されます。これは、選択が2回遅くなり、悪化し、不要なイベント/コードをトリガする可能性があります。

したがって、以下のコードは少なくともWinformsのトリックを行う必要があります。新しいクラスを作成し、TextBox(またはRichTextBox)を(デザイナーに魔法のように表示される新しく作成されたコントロールを使用して)通常の方法で拡張します。私は、使用する区切り文字を指定できる単純なルーチンを作った。もう少し作業すれば、単なる文字の範囲ではなく、より高度な選択方法を作成することも容易です。

リッチテキストボックスの代わりにテキストボックスを使用している場合は、クラス定義で2回表示される「リッチ」ビットを削除するだけです。

class RichTextBoxX : RichTextBox 
{ 
    char delimiter = ','; // Specify what character to use for start and end of selection 

    protected override void WndProc(ref System.Windows.Forms.Message m) 
    { 
     if (m.Msg==0x0203) // WM_LBUTTONDBLCLK 
     { 
      // Perfect situation for off-by-one bugs! Checked thoroughly for at least 10 mins, so should be okay now: 
      int start = this.SelectionStart; 
      if (start < 1) start = 1; 
      int left = this.Text.LastIndexOf(delimiter, start - 1); 
      int right = this.Text.IndexOf(delimiter, start); 
      if (right == -1) right = Text.Length; 
      this.SelectionStart = left + 1; 
      this.SelectionLength = right - left - 1; 
      return;    
     } 

     base.WndProc(ref m); 
    } 
} 
+0

複数の区切り文字を取得するにはどうすればよいですか?char []で例を挙げられますか? – DarkPh03n1X

0

DanWの仕事に追加する複数の区切り記号が追加されていますが、うまくいくようです。

class RichTextBoxX : RichTextBox 
{ 
    private char[] delimiterList = new[] { ',', ' '}; 

    protected override void WndProc(ref System.Windows.Forms.Message m) 
    { 
     if (m.Msg == 0x0203) // WM_LBUTTONDBLCLK 
     { 
      int start = this.SelectionStart; 
      if (start < 1) start = 1; 

      int left = -1; 
      int right = Text.Length; 

      foreach (char c in delimiterList) 
      { 
       if (this.Text.LastIndexOf(c, start - 1) > left) 
       { 
        left = this.Text.LastIndexOf(c, start - 1); 
       } 

       if (this.Text.IndexOf(c, start) < right) 
       { 
        right = this.Text.IndexOf(c, start); 
        if (right == -1) right = Text.Length; 
       } 
      } 

      this.SelectionStart = left + 1; 
      this.SelectionLength = right - left - 1; 
      return; 
     } 

     base.WndProc(ref m); 
    } 
} 

もう一つ:今今、あなたのフォームに、リッチテキストボックスをドラッグアンドドロップする「フォームデザイナ」を使用し、あなたはそれを使用しようとしているフォームの「コード」に上記のコードを貼り付け実装します私の場合のform1.desigener.csにフォームのデザイナークラスに移動し、例えば、実装の文字列を検索:

this.richTextBox1 = new System.Windows.Forms.RichTextBox(); 

と通常のRichTexのように動作します制御し、この後

this.richTextBox1 = new project.form1.RichTextBoxX(); 

と交換余分なオーバライド機能を備えたTBOX実装

1

DarkPh03n1Xから改善答えはほとんど私のために働いていた、しかし、それは厄介なバグがあります。区切り文字はを見つけることができなかった場合を、Text.IndexOf(c, start)-1rightを設定します-1を返します。次にif (right == -1) right = Text.Lengthがトリガーされます。

これで、予想される選択が短くても、テキストの最後まで選択しました。スタートは正しく処理されていると思います。

if (right == -1) right = Text.Lengthを削除しましたが、&& pos != -1を追加しました。ここでは、固定バージョンは次のとおりです。

class RichTextBoxX : RichTextBox 
{ 
    // implement selection to work with "whole words" on double-click 
    // and without selecting the leading/trailing spaces/blanks/line breaks 
    private char[] delimiterList = new[] { '\n', ',', ' ', '(', ')', '_', '/' }; 

    protected override void WndProc(ref Message m) 
    { 
     if (m.Msg == 0x0203) // WM_LBUTTONDBLCLK 
     { 
      int start = SelectionStart; 
      if (start < 1) start = 1; 

      int left = -1; 
      int right = Text.Length; 
      int pos; 

      foreach (char c in delimiterList) 
      { 
       pos = Text.LastIndexOf(c, start - 1); 
       if (pos > left) left = pos; 

       pos = Text.IndexOf(c, start); 
       if (pos < right && pos != -1) right = pos; 
      } 

      SelectionStart = left + 1; 
      SelectionLength = right - left - 1; 
      return; 
     } 

     base.WndProc(ref m); 
    } 
} 

behavourを確認するには、ここで私が使用していたサンプルテキストです:

12.34.56.78 (ab1-2-3-4-5.test-1.example.com) 
Jersey City 
New Jersey 
US, United States 
ASN: Example.com/12345 

私はいくつかの他の区切り文字を追加している、あなたが必要なものを選択して自由に感じます。

関連する問題