TextBoxEx:TextBox {protected override bool ProcessCmdKey(Ref Message msg、Keys keyData){if(keyData ==(Keys.Control | Keys.Back)){SendKeys.SendWait( "^ {LEFT} {BACKSPACE}"); trueを返します。 base.ProcessCmdKey(ref msg、keyData);を返します。 }}
30
10
私は、他のコントロールの中に、一行の入力を可能にするTextBoxを含むWinformsダイアログを持っています。 ユーザーがCtrl-Backspaceを押して単語全体を削除できるようにしたい。 これはデフォルトのTextBoxのデフォルトの動作ではありません。単語を削除するのではなく、_rectangle_文字を受け取ります。
`+ ShortcutsEnabled `プロパティが ` True +`に設定されていることを確認しました。
必要な動作を得るために、TextBoxではなくRichTextBoxを使用できることがわかりました。 これに関する問題は、RichTextBoxの外観(特にボーダー)がTextBoxの外観とは異なること、そしてテキストをマークアップする機能を必要としない、または必要としないことです。
それで、私の質問は、この状況にどう対処するかということです。 TextBoxに欠けているプロパティがありますか? それとも、RichTextBoxを使用し、外観が一貫するように更新し、テキストのマークアップを無効にするのが最善ですか?
これ以上の方法がない場合は、KeyDownイベントとKeyPressイベントを明示的に処理するコードを作成しても嬉しいですが、最初に確認する価値があると思いました。
11 Answer
23
/ *更新:下記のDamirの回答もご覧ください。おそらくより良い解決策です:) * / *
Ctrlキーを押しながら左とBackspaceをTextBoxに送信して、Ctrl Backspaceをシミュレートします。 効果はほぼ同じで、コントロールのテキストを手動で処理する必要はありません。 あなたはこのコードを使ってそれを達成することができます:
TextBoxEx:TextBox {protected override bool ProcessCmdKey(Ref Message msg、Keys keyData){if(keyData ==(Keys.Control | Keys.Back)){SendKeys.SendWait( "^ {LEFT} {BACKSPACE}"); trueを返します。 base.ProcessCmdKey(ref msg、keyData);を返します。 }}
app.configファイルを変更して、SendKeyクラスに新しいキー送信方法を使用させることもできます。
22
昔の質問ですが、余分なコードを必要としない答えを見つけました。
テキストボックスの*自動補完*を有効にすると、CTRL-Backspaceは必要に応じて動作するはずです。
キャレットの左側にある単語全体をCtrl + Backspaceで削除することは、オートコンプリートハンドラの 'rogue feature'のようです。 そのため、オートコンプリートを有効にするとこの問題が解決します。
https://superuser.com/a/332034 [ソース1] | http://blogs.msdn.com/b/oldnewthing/archive/2007/10/11/5395501.aspx [ソース2]
— --
オートコンプリート機能を有効にするには、「+ AutoCompleteMode 」と「 AutoCompleteSource 」を好きなものに設定します(例えば、「 Suggest 」と「 RecentlyUsedList +」)
7
ProcessCmdKeyのオーバーライドはうまく機能しますが、主にSendWaitの使用はキーストロークを模倣するため、Ctrl Backspaceの繰り返しに1回だけに制限されています。バックスペースキーが押されています。 オーバーライドのキーストロークを記録すると、実際には押されたことのない追加のキーのコレクションが見つかります。
別の方法は、ProcessCmdKeyオーバーライドでテキストボックスの外観を明示的に管理し、それ以上システムにキーを送信しないことです。 これはCtrl Deleteにも簡単に適用できます。
Ctrl Backspaceの動作の一般的な「停止点」をいくつか含め、RegExではなくswitchステートメントを使用しました。 彼らは十分にきれいに感じることはありません、そして私は通常キャラクターを見逃してしまう
私のコードに問題があるようでしたら、ぜひ私にお知らせください。 まだこの難問に惑わされている人のために頑張ってください!
TextBoxEx:TextBox {protected override bool ProcessCmdKey(Ref Message msg、Keys keyData){if(keyData ==(Keys.Back | Keys.Control)){(int i = this.SelectionStart - 1; i> 0; i--){switch(Text.Substring(i、1)){// case "":case ";":case "、":case "/":case \\ "が欲しいストップポイントを設定する:Text = Text.Remove(i、SelectionStart - i); SelectionStart = i; trueを返します。 case "\ n":Text = Text.Remove(i - 1、SelectionStart - i); SelectionStart = i; trueを返します。 Clear(); //停止点に到達したことがない場合は、テキストボックス全体が空白になり、trueが返されます。 } else {return base.ProcessCmdKey(ref msg、keyData);} }}}
6
カスタムのKeyDownイベントまたはKeyPressイベントがないと可能であるかどうかはわかりませんが、次のコードは機能します。
private void textBox1_KeyDown(オブジェクト送信側、KeyEventArgs e){if((e.KeyCode == Keys.Back)
3
これは私が使っていたものです、それはまた複数行のテキストボックスを扱います
private void HandleCtrlBackspace_KeyDown(オブジェクト送信側、KeyEventArgs e){switch(e.KeyData){case(Keys.Back | Keys.Control):e.SuppressKeyPress = true; TextBox textbox =(TextBox)送信者。 int i; if(textbox.SelectionStart.Equals(0)){return; int space = textbox.Text.LastIndexOf( ''、textbox.SelectionStart - 1); int line = textbox.Text.LastIndexOf( "\ r \ n"、textbox.SelectionStart - 1); if(space> line){i = space; } else {i =行; } if(i> -1){while(textbox.Text.Substring(i - 1、1).Equals( '')){if(i.Equals(0)){break;} } 私 - ; textbox.Text = textbox.Text.Substring(0、i)textbox.Text.Substring(textbox.SelectionStart); textbox.SelectionStart = i;そうでなければ(i.Equals(-1)){textbox.Text = textbox.Text.Substring(textbox.SelectionStart);破る; }}
2
これはあなたが行く方法です:)
private void textBox1_KeyPress(object sender、KeyPressEventArgs e){// ctrl bcksp if(e.KeyChar == 127){//最後の単語でない場合{//最後の単語のフォームリストを削除して、まとめて戻す(ラムダが大好きです) .Aggregate((a、b)=> a "" b); //選択範囲を最後に設定しますtextBox1.SelectionStart = textBox1.Text.Length;それ以外の場合(textBox1.Text.Split( '').Count()== 1){textBox1.Text = ""; }}}
2
これはうまくいきます:
static Regex RegExWholeWord = new Regex(@ "(\ r \ n | [^ A-Za-z0-9_ \ r \ n]?| \ w?)* $"、RegexOptions.Compiled);
キーダウンでは、
var m = RegExWholeWord.Match(textbox.Text、0、textbox.SelectionStart); if(m.Success){textbox.Text = textbox.Text.Remove(m.Index、m.Length); textbox.SelectionStart = m.Index; }
1
正規表現はこれのために作られました。 これを使って。
private void TextBox_KeyDown(オブジェクト送信側、KeyEventArgs e){TextBox box =(TextBox)送信側; if(e.KeyData ==(Keys.Back | Keys.Control)){if(!box.ReadOnly private void RemoveWord(TextBox box){文字列text = Regex.Replace(box.Text.Substring(0、box.SelectionStart)、@ "(^ \ W)?\ w * \ W * $"、 ""); box.Text = text box.Text.Substring(box.SelectionStart); box.SelectionStart = text.Length; }
0
私はC#ではなくVBで答えています。私はVBでこの解決策を探していましたが、見つけることができませんでした、しかしこれらのC#の応答は私がそれを解決するのを助けました:-D
モジュール内にこのサブを作成する
Public Sub ctrl_bksp(ByRef t As TextBox)整数としてのディメンション= t.SelectionStart整数としてのディム= t.SelectionLength整数としてのディム= t.TextLength '//選択範囲の両側を分割する開始文字列= Strings.Left(t.Text、tl - (tl - ss))Dim strPost文字列= Strings.Right(t.Text、tl - ss - sl) '//整数としてStrPreの最後のスペースの位置を取得= Strings.InStrRev(RTrim(strPre)、 "") strPre = Strings.Left(strPre、s) t.Text = strPre
その後、任意のテキストボックスのKeyPressイベント内からこのsubを呼び出すことができます。
プライベートSub Textbox1_KeyPress(Objectを送信者、System.Windows.Forms.KeyPressEventArgsを処理)Textbox1.KeyPressの選択ケースe.KeyCharのケースChr(127) '// Ctrl Backspace e.Handled = True Callサブ
これは、選択範囲が文字列内のどこにあるか、テキストが選択されているかどうかに関係なく機能し、壮大に反応します。
0
https://stackoverflow.com/users/2121596/dwf[DWF]およびhttps://stackoverflow.com/users/1006021/giangurgolo[giangurgolo]、ご提供いただきありがとうございます。 それの洗練されたバージョンの下に。 これは `ComboBox`も考慮していることに注意してください。それは` TextBox`と全く同じ問題を抱えているからです。 ショートカットは `TextBox`や` ComboBox`の設定が許す場合にのみ有効であることにも注意してください。
TextBoxEx:
パブリッククラスTextBoxEx:TextBox {protected override bool ProcessCmdKey(Ref Message msg、Keys keyData){//注意:// ComboBoxEx.ProcessCmdKey()にも同様のコードが存在します。 //ここでの変更はそこでも適用される必要があるかもしれません。 if(ShortcutsEnabled){if(keyData ==(Keys.Control | Keys.Back)){if(!ReadOnly){if(SelectionStart> 0){int i =(SelectionStart - 1);} //空白を削除します。if(char.IsWhiteSpace(Text、i))i =(StringEx.StartIndexOfSameCharacterClass(Text、i) - 1); //前のマーカーを検索します。if(i> 0)i = StringEx.StartIndexOfSameCharacterClass(Text、i);そうでなければi = 0。 //上記のトリミングで-1になる可能性があるので、iを制限します。 //前のマーカーまたは先頭まで削除します。Text = Text.Remove(i、SelectionStart - i); SelectionStart = i;戻り値(true)。 } else {return(true);} //ホワイトボックスが配置されないように無視します。 else if(keyData ==(Keys.Control | Keys.A)){if(!ReadOnly) return(base.ProcessCmdKey(ref msg、keyData)); }}
ComboxBoxEx:
パブリッククラスComboBoxEx:ComboBox {protected override bool ProcessCmdKey(Ref Message msg、Keys keyData){//注意:// TextBoxEx.ProcessCmdKey()にも同様のコードが存在します。 //ここでの変更はそこでも適用される必要があるかもしれません。 if(keyData ==(Keys.Control | Keys.Back)){if(DropDownStyle!= ComboBoxStyle.DropDownList){if(SelectionStart> 0){int i =(SelectionStart - 1); //空白を削除します。if(char.IsWhiteSpace(Text、i))i =(StringEx.StartIndexOfSameCharacterClass(Text、i) - 1); //前のマーカーを検索します。if(i> 0)i = StringEx.StartIndexOfSameCharacterClass(Text、i);そうでなければi = 0。 //上記のトリミングで-1になる可能性があるので、iを制限します。 //前のマーカーまたは先頭まで削除します。Text = Text.Remove(i、SelectionStart - i); SelectionStart = i;戻り値(true)。 } else {return(true);} //ホワイトボックスが配置されないように無視します。 }}} return(base.ProcessCmdKey(ref msg、keyData)); }}
文字列補助(例: 静的クラスStringEx):
/// /// Returns the start index of the same character class. /// /// The object to process. /// The search starting position. /// /// The zero-based index position of the start of the same character class in the string. /// public static int StartIndexOfSameCharacterClass(string str、int startIndex){int i = startIndex;} if(char.IsWhiteSpace(str、i))// 'IsControl'(、、...)と同様に 'IsSeparator'(Unicodeスペース/行/段落{//区切り文字)を含みます。 (/ * i * /; i> = 0; i--){if(!char.IsWhiteSpace(str、i))の場合(i 1);そうでなければ(char.IsPunctuation(str、i)){((/ * i * /; i> = 0; i--){if(!char.IsPunctuation(str、i))を返す)(i 1) ;そうでなければ(char.IsSymbol(str、i)){((/ * i * /; i> = 0; i--)に対する){if(!char.IsSymbol(str、i))return(i 1) ; else(for(/ * i * /; i> = 0; i--){if(char.IsWhiteSpace(str、i)|| char.IsPunctuation(str、i)|| char.IsSymbol(str、i) i))(i 1)を返す。 }} (0)を返します。 }