Tworzenie pola tekstowego WinForms zachowuje się jak pasek adresu przeglądarki

154

Gdy pole tekstowe C # WinForms otrzymuje fokus, chcę, aby zachowywało się jak pasek adresu przeglądarki.

Aby zobaczyć, co mam na myśli, kliknij pasek adresu przeglądarki internetowej. Zauważysz następujące zachowanie:

  1. Kliknięcie w polu tekstowym powinno zaznaczyć cały tekst, jeśli pole tekstowe nie było wcześniej zaznaczone.
  2. Wskaźnik myszy w dół i przeciągnij w polu tekstowym powinien zaznaczyć tylko tekst, który zaznaczyłem myszą.
  3. Jeśli pole tekstowe jest już fokusem, kliknięcie nie powoduje zaznaczenia całego tekstu.
  4. Skupienie pola tekstowego programowo lub za pomocą klawisza tabulacji na klawiaturze powinno zaznaczyć cały tekst.

Chcę dokładnie to zrobić w WinForms.

OSTRZEŻENIE NAJSZYBSZY PISTOLET: przeczytaj poniższe informacje przed udzieleniem odpowiedzi! Dzięki chłopaki. :-)

Wywołanie .SelectAll () podczas zdarzeń .Enter lub .GotFocus nie zadziała, ponieważ jeśli użytkownik kliknie pole tekstowe, daszek zostanie umieszczony w miejscu, w którym kliknął, usuwając tym samym cały tekst.

Wywołanie .SelectAll () podczas zdarzenia .Click nie zadziała, ponieważ użytkownik nie będzie mógł zaznaczyć myszą żadnego tekstu; wywołanie .SelectAll () będzie nadal nadpisywać zaznaczenie tekstu użytkownika.

Wywołanie BeginInvoke (pole tekstowe (Action ).SelectAll) w zdarzeniu fokus / enter nie działa, ponieważ łamie regułę nr 2 powyżej, będzie nadpisywać zaznaczenie użytkownika na fokusie.

Judah Gabriel Himango
źródło
3
Wyjaśnij, że dotyczy to „RichTextBox”.
Nescio,
Wystarczy Nescio, pole tekstowe lub pole tekstu sformatowanego. Wypróbowałem twoje rozwiązanie również w polu tekstowym.
Judah Gabriel Himango
To wyciek abstrakcji. Najlepszym sposobem na to jest oznaczenie WM_MOUSEACTIVATE i SelectAll na WM_SETFOCUS, jeśli nie WM_MOUSEACTIVATE-ing.
wqw
Wersja WPF: stackoverflow.com/questions/4161531/ ...
Jonathan Allen

Odpowiedzi:

109

Przede wszystkim dziękuję za odpowiedzi! Łącznie 9 odpowiedzi. Dziękuję Ci.

Zła wiadomość: wszystkie odpowiedzi były dziwne lub nie działały poprawnie (lub wcale). Dodałem komentarz do każdego z Twoich postów.

Dobra wiadomość: znalazłem sposób, aby to zadziałało. To rozwiązanie jest dość proste i wydaje się działać we wszystkich scenariuszach (najechanie kursorem, zaznaczanie tekstu, zaznaczanie tabulatorem itp.)

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();
    }
}

O ile wiem, powoduje to, że pole tekstowe zachowuje się dokładnie tak, jak pasek adresu przeglądarki internetowej.

Miejmy nadzieję, że pomoże to następnemu facetowi, który spróbuje rozwiązać ten pozornie prosty problem.

Jeszcze raz dziękuję za wszystkie odpowiedzi, które pomogły mi skierować się na właściwą ścieżkę.

Judah Gabriel Himango
źródło
A co z sytuacją, gdy fokus jest programowo ustawiany na TextBox? Mam ten problem, jak omówiono tutaj: stackoverflow.com/questions/24790704/… Udało mi się go rozwiązać po pewnym czasie, ale nadal się nim denerwuję, ponieważ moja „poprawka” wydaje się raczej niezdarna.
B. Clay Shannon
Napisałeś: „Wywołanie .SelectAll () podczas zdarzeń .Enter lub .GotFocus nie zadziała, ponieważ jeśli użytkownik kliknie pole tekstowe, karetka zostanie umieszczona w miejscu, w którym kliknął, co spowoduje usunięcie zaznaczenia całego tekstu”. Mam SelectAll w zdarzeniu GotFocus, które w większości działa. W rzeczywistości wydaje mi się, że umieszczenie kursora w miejscu kliknięcia przez użytkownika jest „dobrą rzeczą”. Chcę tylko, aby zawsze był zaznaczony, gdy fokus jest programowo ustawiony na TextBox.
B. Clay Shannon
I znowu tu jestem! :)
dotNET,
3
Należy przenieść alreadyFocused = true;mysz MouseUp z instrukcji if. Ponieważ jeśli od razu zaznaczysz fragmenty tekstu, kolejne kliknięcie spowoduje ponowne zaznaczenie całego tekstu.
Robert S.
Poniżej znajduje się jedna linijka odpowiedzi --- BeginInvoke ((Action) MyTextBox.SelectAll); --- Warto obejrzeć. Wydaje się, że robi wszystko, co konieczne
generał Gray
78

Znalazłem prostsze rozwiązanie tego problemu. Obejmuje uruchomienie SelectAll asynchronicznie przy użyciu, Control.BeginInvoketak aby wystąpiło po wystąpieniu zdarzeń Enter i Click:

W C #:

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

W VB.NET (dzięki Krishanu Dey )

Private Sub MyTextBox_Enter(sender As Object, e As EventArgs) Handles MyTextBox.Enter 
    BeginInvoke(DirectCast(Sub() MyTextBox.SelectAll(), Action)) 
End Sub
Duncan Smart
źródło
5
Najmądrzejsza odpowiedź, jaką kiedykolwiek znalazłem… Private Sub MyTextBox_Enter(sender As Object, e As EventArgs) Handles MyTextBox.Enter BeginInvoke(DirectCast(Sub() MyTextBox.SelectAll(), Action)) End Sub
Wielkie
Class Much 'Najlepsze rozwiązanie, taki pasek URL przeglądarki internetowej, dużo klasy End Class
ar.dll
7
W .Net 4.0 możesz: BeginInvoke ((Action) MyTextBox.SelectAll);
JoelFan
2
Niestety, BeginInvoke nie działa dla mnie (niewątpliwie z powodu mojej fatalnie zakurzonej wersji Dot net). Dodanie „Control”. do tego nie pomaga, ani też poprzedzanie nazwy samego TextBox. Sam i blado wałęsający się ...
B. Clay Shannon,
2
Zauważ, że to rozwiązanie nie zachowuje się dokładnie tak, jak opisano w pytaniu. W szczególności Mouse down and drag in the textbox should select only the text I've highlighted with the mouse.nie działa zgodnie z oczekiwaniami. Ale wciąż najkrótsze i najbardziej eleganckie rozwiązanie :)
Marcus Mangelsdorf
30

Twoje rozwiązanie jest dobre, ale zawodzi w jednym konkretnym przypadku. Jeśli ustawisz fokus na TextBox, zaznaczając zakres tekstu zamiast po prostu klikać, flaga jużFocussed nie zostanie ustawiona na wartość true, więc po drugim kliknięciu w TextBox cały tekst zostanie zaznaczony.

Oto moja wersja rozwiązania. Umieściłem również kod w klasie, która dziedziczy TextBox, więc logika jest ładnie ukryta.

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;
        }
    }
}
nżenry
źródło
2
+1 za sugestię niestandardowego pola tekstowego i doskonale działające rozwiązanie!
Tankowany
Rewelacyjne rozwiązanie. Skopiowałem twój kod bezpośrednio do mojego rozwiązania, zmieniłem przestrzeń nazw, aby chronić niewinnych i działało idealnie. Dzięki!
kenswdev
8

To trochę niezdarne, ale w przypadku kliknięcia użyj SendKeys.Send( "{HOME}+{END}" );.

Todd Benning
źródło
Woofta! To trochę włamań! :-) Dzieki za sugestie. Jakieś lepsze pomysły?
Judah Gabriel Himango
Owszem, hakowanie, ale to wcale nie brzmi źle
Terry
3
Weź pod uwagę, że wiele programów antywirusowych przechwytuje i blokuje SEND KEYS jako złośliwe. To nie jest świetne rozwiązanie.
Judah Gabriel Himango
4

Kliknij wydarzenie pola tekstowego? Lub nawet zdarzenie MouseCaptureChanged działa dla mnie. - DOBRZE. nie działa.

Musisz więc zrobić 2 rzeczy:

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; 
}

Działa również do tabulacji (przez textBoxes do jednego) - wywołaj SelectAll () w Enter na wszelki wypadek ...

Jakub Kotrla
źródło
Ok Jakub, to częściowo działa. Jeśli przejdę do pola tekstowego, musi się ono skupić. Czy to zadziała z Twoim rozwiązaniem? (Jeśli możesz mi pokazać, jak,
zaznaczę
Jakub, teraz, gdy opublikowałeś kod, wydaje się, że czasami działa. Nie zawsze; teraz klikam w pole tekstowe i nie zaznaczam wszystkich.
Judah Gabriel Himango
Czasami klikam tekst i nie zaznacza wszystkich. To tak, jakby pole .f nie było ustawione na to, co powinno, a następnie SelectAll nie jest wywoływane. Nie widziałeś tego?
Judah Gabriel Himango
Wiem tylko, że dzięki mouseMouve możesz klikać powoli podczas poruszania myszą (szczególnie na szerokich literach) -> odznacz flagę. Możesz usunąć kod w zdarzeniu mouseMove, ale niż otrzymujesz - po tabbgin do sterowania, a następnie kliknięciu - reSelectAll - nie można wybrać części mieszania przy pierwszym przeciągnięciu
Jakub Kotrla
4

Jedna linia odpowiedzi, której używam ... możesz się kopać ...

W wydarzeniu Enter:

txtFilter.BeginInvoke (new MethodInvoker (txtFilter.SelectAll));


źródło
1
Nie, nie działa. W porządku, zaznacza cały tekst, ale także uniemożliwia użytkownikowi wybranie tylko części tekstu, między innymi.
Judah Gabriel Himango
Przepraszam, chyba źle zrozumiałem zachowanie, którego szukałeś. Po naciśnięciu klawisza Enter zaznacza wszystko, a po kliknięciu i przytrzymaniu zaznacza od początku do kursora. Przypuszczam, że możesz użyć tego, co mam i zastąpić SelectAll własną logiką wyboru. notifywire.com/demos/2009-04-14_1248.swf
Działa świetnie! Pierwsze kliknięcie powoduje wejście do pola; następnie kliknij i przeciągnij, aby zaznaczyć tekst.
D_Bester,
Uwaga: nie działa jak pasek adresu przeglądarki internetowej. Pasek adresu przeglądarki internetowej umożliwia przesuwanie myszy w polu tekstowym i przeciąganie / zaznaczanie, nawet jeśli pole tekstowe nie jest jeszcze aktywne. To rozwiązanie tego nie rozwiązuje. Jeśli nie masz nic przeciwko, fajnie, ale nie spełnia wymagań tego pytania.
Judah Gabriel Himango
3
'Inside the Enter event
TextBox1.SelectAll();

Ok, po wypróbowaniu tutaj jest to, czego chcesz:

  • Na zdarzeniu Enter uruchom flagę, która informuje, że byłeś w zdarzeniu enter
  • W przypadku zdarzenia Click, jeśli ustawisz flagę, wywołaj .SelectAll () i zresetuj flagę.
  • W zdarzeniu MouseMove ustaw wprowadzoną flagę na false, co pozwoli na kliknięcie podświetlenia bez konieczności wcześniejszego wprowadzania pola tekstowego.

Spowoduje to zaznaczenie całego tekstu przy wejściu, ale pozwoliło mi podświetlić część tekstu później lub umożliwić wyróżnienie za pierwszym kliknięciem.

Na żądanie:

    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;
    }

Dla mnie przejście do kontrolki powoduje zaznaczenie całego tekstu.

MagicKat
źródło
Twoje rozwiązanie jest podobne do rozwiązania Jakuba. Działa na kliknięcie. Czy to działa po przejściu tabulatorem do pola tekstowego? (Np. Przejście do paska adresu przeglądarki spowoduje zaznaczenie całego tekstu.)
Judah Gabriel Himango
Tak, działa również w przypadku tabulacji. Napisałem aplikację testową i tak to działało.
MagicKat,
Wydaje się, że nie działa przy tabulacji. Czy możesz nam pokazać kod, który działa w przypadku tabulacji?
Judah Gabriel Himango,
3

Oto funkcja pomocnicza przenosząca rozwiązanie na wyższy poziom - ponowne wykorzystanie bez dziedziczenia.

    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();
            }   
        });
    }

Aby z tego skorzystać, po prostu wywołaj funkcję przekazującą TextBox i zajmie się ona wszystkimi niechlujnymi bitami za Ciebie. Proponuję połączyć wszystkie pola tekstowe w zdarzeniu Form_Load. Możesz umieścić tę funkcję w swoim formularzu lub, jeśli jesteś podobny do mnie, gdzieś w klasie narzędzi do jeszcze większego wykorzystania.

Ross K.
źródło
2

To zadziałało dla WPF / XAML TextBox.

    private bool initialEntry = true;
    private void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
    {
        if (initialEntry)
        {
            e.Handled = true;
            initialEntry = false;
            TextBox.SelectAll();
        }
    }
    private void TextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        TextBox.SelectAll();
        initialEntry = true;      
    }
niechlujstwo
źródło
2

Jest to podobne do popularnej odpowiedzi nzhenry , ale łatwiej mi jest nie tworzyć podklas:

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
Chris
źródło
1

SelectAll nigdy nie działało dla mnie.

To działa.

ActiveControl = textBox1;
textBox1->SelectionStart = 0;
textBox1->SelectionLength = textBox1->Text->Length;
Adam Bruss
źródło
Nie dotyczy to przypadku, w którym naciskanie klawisza Tab w polu tekstowym powoduje skupienie się. Pokazuje również niektóre inne problemy omówione w tym wątku.
Judah Gabriel Himango
1

Znalazłem jeszcze prostsze rozwiązanie:

Aby upewnić się, że cały tekst jest zaznaczony po kliknięciu pola tekstowego, upewnij się, że moduł obsługi kliknięcia wywołuje procedurę obsługi Enter. Nie ma potrzeby stosowania dodatkowych zmiennych!

Przykład:

private void textBox1_Click(object sender, EventArgs e){
        textBox1_Enter(sender, e);
    }

private void textBox1_Enter(object sender, EventArgs e){
        TextBox tb = ((TextBox)sender);
        tb.SelectAll();
    }
Pieter Heemeryck
źródło
To nie działa w przypadku fokusu przez przejście do kontrolki, prawda? A co jeśli chcesz zaznaczyć tekst bez zaznaczania wszystkich?
Judah Gabriel Himango
Właściwie to działa z tabulowaniem! Właśnie przetestowałem to w fałszywym projekcie przy użyciu MS Visual C # 2010. Irytujące w tym rozwiązaniu jest to, że nie możesz zaznaczyć tekstu bez zaznaczenia wszystkich. Jeśli chcesz to zrobić, oczywiście nie jest potrzebny żaden kod, możesz po prostu użyć myszy i wybrać go (lub za pomocą klawiatury).
Pieter Heemeryck
I dlatego to rozwiązanie nie rozwiązuje przedstawionego problemu: nie zachowuje się jak pole adresowe przeglądarki, ponieważ nie można klikać poszczególnych części adresu bez zaznaczenia całego tekstu.
Judah Gabriel Himango
OK, rozumiem co masz na myśli. Tytuł pytania i przykład paska adresu przeglądarki internetowej nie wskazywały, że powinieneś być w stanie zaznaczyć jakąś część tekstu. Wspomniał Pan o tym tylko jako na stronie w ostatnim zdaniu pytania. Pozdrowienia.
Pieter Heemeryck
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();
    }
}
Nescio
źródło
Właśnie przetestowałem z RichTextBox. Nie działa. Kliknięcie w pole tekstowe nie powoduje zaznaczenia całego tekstu. (Ponieważ jest odznaczany po naciśnięciu myszki, kiedy kursor jest umieszczony na kursorze.)
Judah Gabriel Himango
0

Co ciekawe, ComboBox z DropDownStyle = Simple ma prawie dokładnie takie zachowanie, którego szukasz, jak sądzę.

(Jeśli zmniejszysz wysokość kontrolki, aby nie wyświetlać listy - a następnie o kilka pikseli więcej - nie ma efektywnej różnicy między ComboBox a TextBox.)


źródło
Ciekawe, ale naprawdę potrzebuję tego do pracy z TextBox i RichTextBox.
Judah Gabriel Himango,
0

Dlaczego po prostu nie użyjesz MouseDown-Event w polu tekstowym? U mnie działa dobrze i nie wymaga dodatkowych wartości logicznych. Bardzo czysty i prosty, np .:

private void textbox_MouseDown(object sender, MouseEventArgs e) {
    if (textbox != null && !string.IsNullOrEmpty(textbox.Text))
    {
        textbox.SelectAll();
    } }

źródło
Nie, kilka problemów z tym: nie uwzględnia tego, czy pole tekstowe jest już aktywne (nie chcemy zaznaczać - wszystko po każdym naciśnięciu myszki, tylko gdy pole tekstowe nie było fokusu), nie pozwala wybrać tylko fragment tekstu nie działa, gdy fokus zostaje przeniesiony do pola tekstowego za pomocą klawisza Tab.
Judah Gabriel Himango
0

Zadzwoniłem do SelectAll wewnątrz wydarzenia MouseUp i działało dobrze.

    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);
    }
Sreejith K.
źródło
Tak, zobacz inne odpowiedzi (i komentarze), aby dowiedzieć się, dlaczego to nie działa we wszystkich scenariuszach.
Judah Gabriel Himango
Nie sprawdziłem zakładki dla tego rozwiązania. Mój błąd. Dzięki za wskazanie. Cieszę się, że masz teraz kompletne rozwiązanie. Cieszę się również, że moja sugestia dotycząca MouseUp została uwzględniona w Twoim rozwiązaniu.
Sreejith K.
0

Po prostu wyprowadź klasę z TextBox lub MaskedTextBox:

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

I używaj go w swoich formularzach.

Mohammad Mahdipour
źródło
To nie działa. Aby zrozumieć, dlaczego, zapoznaj się z innymi odpowiedziami i komentarzami.
Judah Gabriel Himango
0

W rzeczywistości GotFocus to właściwe wydarzenie (wiadomość naprawdę), które Cię interesuje, ponieważ bez względu na to, jak dojdziesz do kontroli, otrzymasz to nawet w końcu. Pytanie brzmi, kiedy wywołujesz SelectAll ().

Spróbuj tego:

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();
    }
}
Peter Mortensen
źródło
Ali, to nie działa. Spróbuj najechać kursorem na środek tekstu. Przytrzymaj przycisk myszy przez 1 sekundę.
Judah Gabriel Himango
0

Dla grupy pól tekstowych w formularzu:

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;   
}
Yfiua
źródło
1
To nie działa poprawnie; zobacz moje odpowiedzi na inne odpowiedzi, które sugerują .SelectAll (). To nie działa, ponieważ jeśli wejdziesz w pole tekstowe podczas próby zaznaczenia tekstu, przerywa zaznaczenie tekstu, zaznaczając cały tekst. Chcesz zaznaczyć tekst tylko wtedy, gdy fokus wszedł do pola tekstowego za pomocą myszy w górę lub klawiszem Tab, ale jeśli fokus został spowodowany przez naciśnięcie myszy.
Judah Gabriel Himango
0

Wiem, że to już zostało rozwiązane, ale mam sugestię, która moim zdaniem jest raczej prosta.

W przypadku myszki wszystko, co musisz zrobić, to umieścić

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

Wydaje się, że działa dla mnie w VB.NET (wiem, że to jest pytanie C # ... niestety jestem zmuszony używać VB w mojej pracy ... i miałem ten problem, który mnie tu sprowadził ... )

Nie znalazłem jeszcze żadnych problemów ... poza tym, że nie wybiera od razu po kliknięciu, ale miałem z tym problemy ....

Eluem
źródło
1
Pierwotna prośba chciała, aby to zadziałało również po wejściu w pole.
Don Kirkby
2
Tak, to nie działa dla wszystkich scenariuszy. Działa tylko po kliknięciu w pole tekstowe. Nawet wtedy, jeśli nie zachowuje się tak, jak pasek adresu przeglądarki zachowuje się, gdy zaznaczenie już istnieje w polu tekstowym.
Judah Gabriel Himango
0

Poniższe rozwiązanie działa dla mnie. Dodałem OnKeyDowni OnKeyUpnadpisanie zdarzenia, aby tekst TextBox był zawsze zaznaczony.

    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;
    }
}
abrfra
źródło
2
Czy pozwala na przesuwanie myszy w dół do pola tekstowego, przeciąganie kursora, aby zaznaczyć tekst, a następnie przesuwanie myszy w górę?
Judah Gabriel Himango
0

Ustaw selekcję po opuszczeniu sterowania. Będzie tam, kiedy wrócisz. Tabulator wokół formularza i po powrocie do kontrolki cały tekst zostanie zaznaczony.

Jeśli wejdziesz myszą, karetka zostanie umieszczona w miejscu, w którym kliknąłeś.

private void maskedTextBox1_Leave(object sender, CancelEventArgs e)
    {
        maskedTextBox1.SelectAll();
    }
Joel
źródło
Jeśli wejdziesz myszą, powinien zaznaczyć cały tekst, chyba że jest już fokus. To nie potwierdza tego.
Judah Gabriel Himango
0

Bardzo proste rozwiązanie:

    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;
        }
    }

EDYCJA: Oryginalny OP był w szczególności zaniepokojony sekwencją przesuwania myszy / zaznaczania tekstu / przesuwania myszy, w którym to przypadku powyższe proste rozwiązanie kończyłoby się częściowym zaznaczeniem tekstu.

To powinno * rozwiązać problem (w praktyce przechwytuję 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 );
    }

* Właściwie następująca sekwencja kończy się częściowym zaznaczeniem tekstu, ale jeśli najedziesz myszą na pole tekstowe, cały tekst zostanie ponownie zaznaczony:

mouse-down / text-selection / mouse-move-out-textbox / mouse-up

Mauro Sampietro
źródło
To rozwiązanie zostało już opublikowane. Zobacz komentarz do istniejącej odpowiedzi, aby dowiedzieć się, dlaczego to nie działa.
Judah Gabriel Himango,
działa z tabulatorem i myszą, możesz uzyskać fokus, zaznaczyć tekst, a następnie mysz w górę. Nie mogę znaleźć problemu z tym. Czy możesz to wskazać?
Mauro Sampietro
0

Uważam, że to działa najlepiej, gdy klikam myszą i nie puszczam natychmiast:

    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;
    }
user3729779
źródło
0

Moje rozwiązanie jest dość prymitywne, ale działa dobrze w moim celu

private async void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (sender is TextBox)
    {
        await Task.Delay(100);
        (sender as TextBox).SelectAll();
    }
}
BlueWizard
źródło
Nie działa, gdy chcesz najechać myszą, aby zaznaczyć fragment tekstu, przeciągnąć myszą, a następnie w górę. Twój kod wyczyści zaznaczenie i zaznaczy wszystko.
Judah Gabriel Himango
@JudahHimango Jup. Jeśli klikniesz jedno kliknięcie, zaznaczy wszystko. Jeśli klikniesz i przeciągniesz, zaznaczy tylko zaznaczenie. Przynajmniej pasek przeglądarki w przeglądarce Firefox pokazuje dokładnie to zachowanie.
BlueWizard,
Czy nie jest to jednak stan wyścigu? Jeśli uda mi się szybko zaznaczyć jakiś tekst myszą, to .SelectAll () uruchomi się kilka milisekund później, nadpisując mój wybór.
Judah Gabriel Himango
1
Ok, jeśli szybko wybierasz rzeczy, ta rzecz będzie działać przeciwko tobie.
BlueWizard
-1

Poniższe wydaje się działać. Zdarzenie enter obsługuje tabulacja do kontrolki, a MouseDown działa po kliknięciu kontrolki.

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

    private void textBox1_MouseDown(object sender, MouseEventArgs e)
    {
        if (textBox1.Focused)
            textBox1.SelectAll();
    }
benPearce
źródło
Nie ma szczęścia, nie działa, obawiam się. Spróbuj zaznaczyć jakiś tekst. Tekst .SelectAll zastępuje to, co użytkownik próbuje zaznaczyć.
Judah Gabriel Himango,
-1

Odpowiedź może być w rzeczywistości znacznie prostsza niż WSZYSTKIE powyższe, na przykład (w WPF):

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

oczywiście nie wiem, jak chcesz użyć tego kodu, ale główna część do obejrzenia to: Najpierw wywołaj .Focus (), a następnie wywołaj .SelectAll ();

MDB
źródło
To nie działa i jest duplikatem innych odpowiedzi. Na przykład, jeśli przesuniesz kursor myszy w polu tekstowym, przeciągnij, powinno ono zaznaczyć część tekstu. To łamie to i nie zaznacza wszystkich.
Judah Gabriel Himango
-1

po prostu użyj selectall () w zdarzeniach enter i kliknij

private void textBox1_Enter(object sender, EventArgs e)
        {

            textBox1.SelectAll();
        }
        private void textBox1_Click(object sender, EventArgs e)
        {
            textBox1.SelectAll();
        }
EKanadily
źródło
To działa, dopóki nie chcesz zaznaczyć tekstu. Zobacz inne odpowiedzi, aby uzyskać pełne wyjaśnienie.
Judah Gabriel Himango
-1

Stworzyłem nowy projekt VB.Net Wpf. Utworzyłem jeden TextBox i użyłem następującego za kodem:

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
BSalita
źródło