163

C# WinForms テキスト ボックスがフォーカスを受け取ると、ブラウザーのアドレス バーのように動作するようにします。

意味を理解するには、Web ブラウザのアドレス バーをクリックしてください。次の動作に気付くでしょう。

  1. テキストボックスが以前にフォーカスされていなかった場合、テキストボックスをクリックするとすべてのテキストが選択されます。
  2. テキスト ボックス内でマウスを押してドラッグすると、マウスで強調表示したテキストのみが選択されます。
  3. テキスト ボックスが既にフォーカスされている場合、クリックしてもすべてのテキストが選択されるわけではありません。
  4. プログラムまたはキーボードのタブ操作でテキスト ボックスにフォーカスすると、すべてのテキストが選択されます。

私はWinFormsでこれを正確にやりたいです。

FASTEST GUN ALERT: 回答する前に以下をお読みください! みんなありがとう。:-)

.Enter または .GotFocus イベント中に .SelectAll() を呼び出しても機能しません。ユーザーがテキスト ボックスをクリックすると、クリックした場所にキャレットが配置され、すべてのテキストの選択が解除されるためです。

ユーザーがマウスでテキストを選択できないため、.Click イベント中に .SelectAll() を呼び出しても機能しません。.SelectAll() 呼び出しは、ユーザーのテキスト選択を上書きし続けます。

上記のルール 2 に違反するため、フォーカス/入力イベント enter で BeginInvoke((Action)textbox.SelectAll) を呼び出しても機能しません。フォーカス時にユーザーの選択をオーバーライドし続けます。

4

31 に答える 31

112

まず第一に、答えてくれてありがとう!合計9つの答え。ありがとうございました。

悪いニュース: すべての回答に癖があったか、正しく機能しなかった (またはまったく機能しなかった)。各投稿にコメントを追加しました。

良いニュース: それを機能させる方法を見つけました。このソリューションは非常に簡単で、すべてのシナリオ (マウス ダウン、テキストの選択、フォーカスのタブ移動など) で機能するようです。

bool alreadyFocused;

...

textBox1.GotFocus += textBox1_GotFocus;
textBox1.MouseUp += textBox1_MouseUp;
textBox1.Leave += textBox1_Leave;

...

void textBox1_Leave(object sender, EventArgs e)
{
    alreadyFocused = false;
}


void textBox1_GotFocus(object sender, EventArgs e)
{
    // Select all text only if the mouse isn't down.
    // This makes tabbing to the textbox give focus.
    if (MouseButtons == MouseButtons.None)
    {
        this.textBox1.SelectAll();
        alreadyFocused = true;
    }
}

void textBox1_MouseUp(object sender, MouseEventArgs e)
{
    // Web browsers like Google Chrome select the text on mouse up.
    // They only do it if the textbox isn't already focused,
    // and if the user hasn't selected all text.
    if (!alreadyFocused && this.textBox1.SelectionLength == 0)
    {
        alreadyFocused = true;
        this.textBox1.SelectAll();
    }
}

私が知る限り、これにより、テキスト ボックスは Web ブラウザーのアドレス バーとまったく同じように動作します。

願わくば、これがこの一見単純な問題を解決しようとする次の人に役立つことを願っています。

皆さん、私を正しい道に導くのに役立ったすべての回答に感謝します。

于 2008-09-19T14:08:30.040 に答える
83

これに対するより簡単な解決策を見つけました。Control.BeginInvokeEnter および Click イベントが発生した後に発生するように、SelectAll を非同期的に開始する必要があります。

C# の場合:

private void MyTextBox_Enter(object sender, EventArgs e)
{
    // Kick off SelectAll asynchronously so that it occurs after Click
    BeginInvoke((Action)delegate
    {
        MyTextBox.SelectAll();
    });
}

VB.NET で ( Krishanu Deyに感謝)

Private Sub MyTextBox_Enter(sender As Object, e As EventArgs) Handles MyTextBox.Enter 
    BeginInvoke(DirectCast(Sub() MyTextBox.SelectAll(), Action)) 
End Sub
于 2011-07-28T10:12:58.473 に答える
30

あなたのソリューションは優れていますが、ある特定のケースで失敗します。単にクリックするのではなく、テキストの範囲を選択して TextBox にフォーカスを与えると、 alreadyFocussed フラグが true に設定されないため、TextBox を 2 回目にクリックすると、すべてのテキストが選択されます。

これが私のバージョンのソリューションです。また、TextBox を継承するクラスにコードを配置したので、ロジックはうまく隠されています。

public class MyTextBox : System.Windows.Forms.TextBox
{
    private bool _focused;

    protected override void OnEnter(EventArgs e)
    {
        base.OnEnter(e);
        if (MouseButtons == MouseButtons.None)
        {
            SelectAll();
            _focused = true;
        }
    }

    protected override void OnLeave(EventArgs e)
    {
        base.OnLeave(e);
        _focused = false;
    }

    protected override void OnMouseUp(MouseEventArgs mevent)
    {
        base.OnMouseUp(mevent);
        if (!_focused)
        {
            if (SelectionLength == 0)
                SelectAll();
            _focused = true;
        }
    }
}
于 2010-09-09T17:14:09.027 に答える
8

少し面倒ですが、クリックイベントでSendKeys.Send( "{HOME}+{END}" );.

于 2008-09-18T22:08:28.097 に答える
4

テキストボックスのクリックイベント?または、MouseCaptureChanged イベントでさえも機能します。- わかった。動作しません。

したがって、次の 2 つのことを行う必要があります。

private bool f = false;

private void textBox_MouseClick(object sender, MouseEventArgs e)
{ 
  if (this.f) { this.textBox.SelectAll(); }
  this.f = false;
}

private void textBox_Enter(object sender, EventArgs e)
{
  this.f = true;
  this.textBox.SelectAll();
}
private void textBox_MouseMove(object sender, MouseEventArgs e) // idea from the other answer
{
  this.f = false; 
}

タブ移動(テキストボックスを介して)にも機能します-念のためにEnterでSelectAll()を呼び出します...

于 2008-09-18T22:07:28.987 に答える
4

私が使用する1行の回答...あなたは自分を蹴っているかもしれません...

Enter イベントで:

txtFilter.BeginInvoke(新しい MethodInvoker( txtFilter.SelectAll));

于 2009-04-06T20:03:28.723 に答える
3
'Inside the Enter event
TextBox1.SelectAll();

わかりました、それを試した後、ここにあなたが望むものがあります:

  • Enter イベントで、Enter イベントに参加したことを示すフラグを開始します。
  • Click イベントで、フラグを設定した場合は、.SelectAll() を呼び出してフラグをリセットします。
  • MouseMove イベントで、entered フラグを false に設定します。これにより、最初にテキスト ボックスに入力しなくてもハイライトをクリックできるようになります。

これにより、入力時にすべてのテキストが選択されましたが、後でテキストの一部を強調表示したり、最初のクリックで強調表示したりできました。

リクエストにより:

    bool entered = false;
    private void textBox1_Enter(object sender, EventArgs e)
    {
        entered = true;
        textBox1.SelectAll();   //From Jakub's answer.
    }

    private void textBox1_Click(object sender, EventArgs e)
    {
        if (entered) textBox1.SelectAll();
        entered = false;
    }

    private void textBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (entered) entered = false;
    }

私にとっては、コントロールにタブで移動すると、すべてのテキストが選択されます。

于 2008-09-18T22:09:27.640 に答える
3

ソリューションを次のレベルに引き上げるヘルパー関数を次に示します - 継承なしで再利用します。

    public static void WireSelectAllOnFocus( TextBox aTextBox )
    {
        bool lActive = false;
        aTextBox.GotFocus += new EventHandler( ( sender, e ) =>
        {
            if ( System.Windows.Forms.Control.MouseButtons == MouseButtons.None )
            {
                aTextBox.SelectAll();
                lActive = true;
            }
        } );

        aTextBox.Leave += new EventHandler( (sender, e ) => {
            lActive = false;
        } );

        aTextBox.MouseUp += new MouseEventHandler( (sender, e ) => {
            if ( !lActive )
            {
                lActive = true;
                if ( aTextBox.SelectionLength == 0 ) aTextBox.SelectAll();
            }   
        });
    }

これを使用するには、TextBox を渡す関数を呼び出すだけで、面倒な部分はすべて処理されます。Form_Load イベントですべてのテキスト ボックスを配線することをお勧めします。この関数をフォームに配置することも、私のような場合はユーティリティ クラスのどこかに配置して、さらに再利用することもできます。

于 2011-08-07T05:34:30.703 に答える
2

これはnzhenryの一般的な回答に似ていますが、サブクラス化する必要がない方が簡単だと思います:

Private LastFocused As Control = Nothing

Private Sub TextBox1_Enter(sender As Object, e As System.EventArgs) Handles TextBox1.Enter, TextBox2.Enter, TextBox3.Enter
    If MouseButtons = Windows.Forms.MouseButtons.None Then LastFocused = sender
End Sub

Private Sub TextBox1_Leave(sender As Object, e As System.EventArgs) Handles TextBox1.Leave, TextBox2.Leave, TextBox3.Leave
    LastFocused = Nothing
End Sub

Private Sub TextBox1_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles TextBox1.MouseUp, TextBox2.MouseUp, TextBox3.MouseUp
    With CType(sender, TextBox)
        If LastFocused IsNot sender AndAlso .SelectionLength = 0 Then .SelectAll()
    End With
    LastFocused = sender
End Sub
于 2012-05-02T15:03:31.083 に答える
1

SelectAll は私にとってはうまくいきませんでした。

これは機能します。

ActiveControl = textBox1;
textBox1->SelectionStart = 0;
textBox1->SelectionLength = textBox1->Text->Length;
于 2012-05-02T20:13:25.380 に答える
0
private bool _isSelected = false;
private void textBox_Validated(object sender, EventArgs e)
{
    _isSelected = false;
}

private void textBox_MouseClick(object sender, MouseEventArgs e)
{
    SelectAllText(textBox);
}

private void textBox_Enter(object sender, EventArgs e)
{
    SelectAllText(textBox);
}

private void SelectAllText(TextBox text)
{
    if (!_isSelected)
    {
        _isSelected = true;
        textBox.SelectAll();
    }
}
于 2008-09-18T22:31:05.903 に答える
0

実際、GotFocusは、あなたが興味を持っている正しいイベント(本当にメッセージ)です。どのようにコントロールに到達しても、最終的にはこれを取得するからです。問題は、いつSelectAll()を呼び出すかです。

これを試して:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        this.textBox1.GotFocus += new EventHandler(textBox1_GotFocus);
    }

    private delegate void SelectAllDelegate();    
    private IAsyncResult _selectAllar = null; //So we can clean up afterwards.

    //Catch the input focus event
    void textBox1_GotFocus(object sender, EventArgs e)
    {
        //We could have gotten here many ways (including mouse click)
        //so there could be other messages queued up already that might change the selection.
        //Don't call SelectAll here, since it might get undone by things such as positioning the cursor.
        //Instead use BeginInvoke on the form to queue up a message
        //to select all the text after everything caused by the current event is processed.
        this._selectAllar = this.BeginInvoke(new SelectAllDelegate(this._SelectAll));
    }

    private void _SelectAll()
    {
        //Clean-up the BeginInvoke
        if (this._selectAllar != null)
        {
            this.EndInvoke(this._selectAllar);
        }
        //Now select everything.
        this.textBox1.SelectAll();
    }
}
于 2008-09-19T07:58:25.383 に答える
0

TextBox または MaskedTextBox からクラスを派生させるだけです。

public class SMaskedTextBox : MaskedTextBox
{
    protected override void OnGotFocus(EventArgs e)
    {
        base.OnGotFocus(e);
        this.SelectAll();
    }
}

そして、それをフォームで使用してください。

于 2010-01-06T05:21:03.937 に答える
0

MSDN フォーラムの "Windows Forms General"で提案されている、単に TextBox をサブクラス化するソリューションを試しましたか?

于 2008-12-22T09:18:47.650 に答える
0

私のソリューションはかなり原始的ですが、私の目的には問題なく機能します

private async void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (sender is TextBox)
    {
        await Task.Delay(100);
        (sender as TextBox).SelectAll();
    }
}
于 2015-07-19T14:21:03.103 に答える
0

MouseUp イベント内で SelectAll を呼び出したところ、問題なく動作しました。

    private bool _tailTextBoxFirstClick = false;

    private void textBox1_MouseUp(object sender, MouseEventArgs e)
    {
        if(_textBoxFirstClick)           
            textBox1.SelectAll();

        _textBoxFirstClick = false;
    }  

    private void textBox1_Leave(object sender, EventArgs e)
    {
        _textBoxFirstClick = true;
        textBox1.Select(0, 0);
    }
于 2009-10-26T15:19:32.273 に答える
0

興味深いことに、DropDownStyle=Simple を指定した ComboBox は、探している動作とほとんど同じだと思います。

(リストを表示しないようにコントロールの高さを減らしてから、さらに数ピクセル減らすと、ComboBox と TextBox の間に実質的な違いはありません。)

于 2008-09-18T22:54:38.670 に答える
0

コントロールを離れるときの選択を設定します。あなたが戻ってきたとき、それはそこにあるでしょう。フォームをタブで囲み、コントロールに戻ると、すべてのテキストが選択されます。

マウスで入ると、クリックした場所にキャレットが正しく配置されます。

private void maskedTextBox1_Leave(object sender, CancelEventArgs e)
    {
        maskedTextBox1.SelectAll();
    }
于 2013-06-20T18:31:24.203 に答える
0

フォーム内のテキスト ボックスのグループの場合:

private System.Windows.Forms.TextBox lastFocus;   

private void textBox_GotFocus(object sender, System.Windows.Forms.MouseEventArgs e)   
{
    TextBox senderTextBox = sender as TextBox;
    if (lastFocus!=senderTextBox){
        senderTextBox.SelectAll();
    }
    lastFocus = senderTextBox;   
}
于 2011-05-23T18:35:43.810 に答える
0

テキスト ボックスの MouseDown イベントを単純に使用しないのはなぜですか。それは私にとってはうまく機能し、追加のブール値は必要ありません。非常にクリーンでシンプルです。例:

private void textbox_MouseDown(object sender, MouseEventArgs e) {
    if (textbox != null && !string.IsNullOrEmpty(textbox.Text))
    {
        textbox.SelectAll();
    } }
于 2008-11-10T07:07:48.017 に答える
0

非常に簡単な解決策:

    private bool _focusing = false;

    protected override void OnEnter( EventArgs e )
    {
        _focusing = true;
        base.OnEnter( e );
    }

    protected override void OnMouseUp( MouseEventArgs mevent )
    {
        base.OnMouseUp( mevent );

        if( _focusing )
        {
            this.SelectAll();
            _focusing = false;
        }
    }

編集:元の OP は、マウスダウン/テキスト選択/マウスアップのシーケンスに特に関心がありました。その場合、上記の単純な解決策では、テキストが部分的に選択されてしまいます。

これで問題が解決するはずです*(実際にはWM_SETCURSORをインターセプトします):

    protected override void WndProc( ref Message m )
    {
        if( m.Msg == 32 ) //WM_SETCURSOR=0x20
        {
              this.SelectAll(); // or your custom logic here                
        }

        base.WndProc( ref m );
    }

*実際には、次のシーケンスは部分的なテキスト選択で終了しますが、マウスをテキストボックスの上に移動すると、すべてのテキストが再び選択されます:

マウスダウン / テキスト選択 / マウスムーブアウトテキストボックス / マウスアップ

于 2014-09-23T15:03:56.030 に答える
0

これはすでに解決されていることは知っていますが、実際にはかなり単純だと思う提案があります。

マウスアップイベントでは、配置するだけです

if(textBox.SelectionLength = 0)
{
    textBox.SelectAll();
}

VB.NETでうまくいくようです(これはC#の質問であることは知っています...悲しいことに、仕事でVBを使用することを余儀なくされています..そして、私はこの問題を抱えていました。それが私をここに連れてきたものです... )

クリックしてもすぐに選択されないという事実を除いて、まだ問題は見つかりませんでしたが、問題がありました....

于 2012-01-13T16:30:15.370 に答える
0

次の解決策は私にとってはうまくいきます。TextBox テキストを常に選択状態に保つために、イベント オーバーライドを追加OnKeyDownしました。OnKeyUp

    public class NumericTextBox : TextBox
{
    private bool _focused;
    protected override void OnGotFocus(EventArgs e)
    {
        base.OnGotFocus(e);
        if (MouseButtons == MouseButtons.None)
        {
            this.SelectAll();
            _focused = true;
        }
    }
    protected override void OnEnter(EventArgs e)
    {
        base.OnEnter(e);
        if (MouseButtons == MouseButtons.None)
        {
            SelectAll();
            _focused = true;
        }
    }

    protected override void OnLeave(EventArgs e)
    {
        base.OnLeave(e);
        _focused = false;
    }

    protected override void OnMouseUp(MouseEventArgs mevent)
    {
        base.OnMouseUp(mevent);
        if (!_focused)
        {
            if (SelectionLength == 0)
                SelectAll();
            _focused = true;
        }
    }

    protected override void OnKeyUp(KeyEventArgs e)
    {
        base.OnKeyUp(e);

        if (SelectionLength == 0)
            SelectAll();
        _focused = true;
    }
    protected override void OnKeyDown(KeyEventArgs e)
    {
       base.OnKeyDown(e);
       if (SelectionLength == 0)
            SelectAll();
        _focused = true;
    }
}
于 2012-08-31T08:56:11.643 に答える
0

マウスをクリックしてすぐに離さないと、これが最もうまくいくと思います:

    private bool SearchBoxInFocusAlready = false;
    private void SearchBox_LostFocus(object sender, RoutedEventArgs e)
    {
        SearchBoxInFocusAlready = false;
    }

    private void SearchBox_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        if (e.ButtonState == MouseButtonState.Released && e.ChangedButton == MouseButton.Left &&
            SearchBox.SelectionLength == 0 && SearchBoxInFocusAlready == false)
        {
            SearchBox.SelectAll();
        }

        SearchBoxInFocusAlready = true;
    }
于 2015-05-27T15:43:07.817 に答える
-1

以下はうまくいくようです。enterイベントはコントロールへのタブ移動を処理し、コントロールがクリックされるとMouseDownが機能します。

    private ########### void textBox1_Enter(object sender, EventArgs e)
    {
        textBox1.SelectAll();
    }

    private void textBox1_MouseDown(object sender, MouseEventArgs e)
    {
        if (textBox1.Focused)
            textBox1.SelectAll();
    }
于 2008-09-18T22:42:15.503 に答える
-1

新しい VB.Net Wpf プロジェクトを作成しました。TextBox を 1 つ作成し、コード ビハインドに以下を使用しました。

Class MainWindow 

    Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        AddHandler PreviewMouseLeftButtonDown, New MouseButtonEventHandler(AddressOf SelectivelyIgnoreMouseButton)
        AddHandler GotKeyboardFocus, New KeyboardFocusChangedEventHandler(AddressOf SelectAllText)
        AddHandler MouseDoubleClick, New MouseButtonEventHandler(AddressOf SelectAllText)
    End Sub

    Private Shared Sub SelectivelyIgnoreMouseButton(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
        ' Find the TextBox
        Dim parent As DependencyObject = TryCast(e.OriginalSource, UIElement)
        While parent IsNot Nothing AndAlso Not (TypeOf parent Is TextBox)
            parent = VisualTreeHelper.GetParent(parent)
        End While

        If parent IsNot Nothing Then
            Dim textBox As Object = DirectCast(parent, TextBox)
            If Not textBox.IsKeyboardFocusWithin Then
                ' If the text box is not yet focussed, give it the focus and
                ' stop further processing of this click event.
                textBox.Focus()
                e.Handled = True
            End If
        End If
    End Sub

    Private Shared Sub SelectAllText(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Dim textBox As Object = TryCast(e.OriginalSource, TextBox)
        If textBox IsNot Nothing Then
            textBox.SelectAll()
        End If
    End Sub

End Class
于 2010-04-15T18:05:13.770 に答える
-1

これは.NET 2005で機能しています-

    ' * if the mouse button is down, do not run the select all.
    If MouseButtons = Windows.Forms.MouseButtons.Left Then
        Exit Sub
    End If

 ' * OTHERWISE INVOKE THE SELECT ALL AS DISCUSSED.
于 2015-12-01T19:25:23.747 に答える
-1

答えは、実際には上記のすべてよりもはるかに単純です。たとえば、(WPF で):

public void YourTextBox_MouseEnter(object sender, MouseEventArgs e)
    {
        YourTextBox.Focus();
        YourTextBox.SelectAll();
    }

もちろん、このコードをどのように使用したいかはわかりませんが、ここで注目すべき主要部分は次のとおりです。最初に .Focus() を呼び出し、次に .SelectAll(); を呼び出します。

于 2014-04-02T13:19:38.213 に答える