Laden...

Text in TextBox bei Focus markieren

Erstellt von miketech vor 18 Jahren Letzter Beitrag vor 9 Jahren 24.365 Views
M
miketech Themenstarter:in
82 Beiträge seit 2005
vor 18 Jahren
Text in TextBox bei Focus markieren

Hallo zusammen,

ich will etwas eigentlich relativ simples erreichen:

Wenn man den Focus auf eine bestimmte TextBox setzt soll der gesamte Text in dieser Textbox markiert werden. Ich habe hierfür das Event "Enter" implementiert:

mit:

searchTextBox.SelectAll();

Das funktioniert aber nicht. Hat jemand eine Idee, wieso?

Gruß

Mike

S
8.746 Beiträge seit 2005
vor 18 Jahren

Funktioniert tadellos. Muss an deinem restlichen Code liegen.

G
38 Beiträge seit 2005
vor 18 Jahren

Hallo miketech,

ich hab das mal eben schnell nachvollzogen.
Wenn ich die TextBox mit Tab anwähle, funktioniert das, wie svenson schon sagt, tadellos. Wenn ich sie allerdings mit der Maus anwähle, ist mein Text nicht selektiert.
Was folgere ich daraus?
Der Mausklick setzt die Position des Cursors NACHDEM alles selektiert wurde und hebt damit die Auswahl auf, was ja auch irgendwo logisch ist.

Musst dann wohl eher auf die Mouse-Events reagieren statt auf das Enter.
Probier's mal aus und gib ne Rückmeldung.

Gruß vom gn0m

Edit:
Ich mein natürlich den MouseUp-Event, hatte ich oben nicht ganz so klar ausgedrückt 😉

M
miketech Themenstarter:in
82 Beiträge seit 2005
vor 18 Jahren

Hm, das ist ja komisch. Wenn ich z.B.:

searchTextBox.Text = "";

mache, funktionierts das. Aber SelectAll() will irgenwdie nicht 😐

Gruß

Mike

M
miketech Themenstarter:in
82 Beiträge seit 2005
vor 18 Jahren

Ah ok, danke. Das teste ich mal.

Mike

G
38 Beiträge seit 2005
vor 18 Jahren

Hallo miketech,

ich hab das mit dem MouseUp-Event gerade getestet, funktioniert super.
Wenn deine Methode natürlich auch funktioniert, wunderbar.
Ansonsten reagier, wie gesagt, einfach auf das MouseUp-Event und du hast den Effekt, den du (so weit ich das verstanden hab 😉) wolltest.

Gruß vom gn0m

M
miketech Themenstarter:in
82 Beiträge seit 2005
vor 18 Jahren

Ok, also im Click Event funktionierts. Danke!

Gruß

Mike

M
miketech Themenstarter:in
82 Beiträge seit 2005
vor 18 Jahren

Ok, wie gesagt: Mit Click gehts auch, ebenso mit Mouse Down.

Gruß

Mike

G
38 Beiträge seit 2005
vor 18 Jahren

Hallo miketech,

na, dann is ja alles in Butter 🙂
Freut mich, dass ich auch endlich mal jemandem weiterhelfen konnte 😁

Gruß vom gn0m

M
miketech Themenstarter:in
82 Beiträge seit 2005
vor 18 Jahren

Hi,

hm irgendwie ist das doch nicht ganz optimal 🙂 Das Problem ist ja jetzt, dass immer, wenn ich mit der Maus draufklicke alles markiert wird. Das wollte ich ja nur, wenn das Feld den Focus bekommt. D.h. jetzt ist es so, dass ich den Cursor gar nicht mehr positionieren kann, weil jedes mal wenn ich mit der Maus versuche den Cursor zu platzieren wird ja alles markiert 🙂

Muss ich nun irgendwie nen Hack bauen, dass bei Focus ein Flag gesetzt wird, dass das Eingabefeld den Focus hat und ich dann nur selectAll ausführe, wenn es vorher noch nicht den focus hatte? Oder geht das auch einfacher?

Gruß

Mike

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo miketech,

ich denke, es geht nicht einfacher.

herbivore

B
14 Beiträge seit 2009
vor 13 Jahren

Der Thread ist schon etwas älter, aber ich steh gerade vor genau dem gleichen Problem, was auf den ersten Blick zwar ziemlich trivial aussieht, es aber anscheinend doch nicht ist. Wenn ich die hier vorgeschlagene Lösung richtig verstehe, löst sie das Problem auch nicht:

Muss ich nun irgendwie nen Hack bauen, dass bei Focus ein Flag gesetzt wird, dass das Eingabefeld den Focus hat und ich dann nur selectAll ausführe, wenn es vorher noch nicht den focus hatte?

Wenn die TextBox durch Drücken der Tab-Taste fokussiert wurde, würde auch das Flag gesetzt werden. Wenn die TextBox also zuerst durch Tab fokussiert wird und anschließend mit der Maus auf die TextBox geklickt wird, würde der Text erneut markiert werden.

Wie kann man also den Text in einer TextBox jedes Mal, wenn sie fokussiert wird (aber vorher noch nicht den Fokus hatte), markieren?

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo BcVcB,

Wenn die TextBox also zuerst durch Tab fokussiert wird und anschließend mit der Maus auf die TextBox geklickt wird, würde der Text erneut markiert werden.

nein, gerade nicht, weil du ja das Flag gesetzt hast.

Das Problem ist tatsächlich so trivial, wie es scheint. Natürlich muss man nicht unbedingt ein Flag nehmen. Man kann sich auch in einer Variable vom Typ Control das Control merken, das gerade den Focus hat. Es reicht ein einziger EventHandler, der für alle Controls registriert wird und der die Variable setzt und (nur) wenn sich dadurch etwas ändert, den kompletten Text markiert.

herbivore

B
14 Beiträge seit 2009
vor 13 Jahren

Also ich hab jetzt diesen Code geschrieben (auf der Form befinden sich nur 2 Textboxen, die beide auf das Enter- und MouseDown-Ereignis reagieren):

public partial class Form1 : Form
{
	bool focusChanged = false;

	public Form1() {
		InitializeComponent();
	}

	private void textBox_Enter(object sender, EventArgs e) {
		((TextBox)sender).SelectAll();
		focusChanged = true;
	}

	private void textBox_MouseDown(object sender, MouseEventArgs e) {
		if (focusChanged) {
			((TextBox)sender).SelectAll();
			focusChanged = false;
		}
	}
}

Wenn man nun zuerst mit Tab die fokussierte Textbox wechselt, wird korrekterweise der Text darin markiert. Auch wenn man mit der Maus auf eine Textbox klickt, die vorher noch nicht den Fokus hatte, wird wie gewünscht der Text darin markiert.

Wenn ich nun aber zunächst mit Tab eine Textbox fokussiere und dann mit der Maus auf diese bereits fokussierte Textbox klicke, wird der Text darin wieder markiert (bzw bleibt markiert). Erst wenn ich dann ein weiteres Mal darauf klicke, wird die Markierung aufgehoben.

Wenn man statt eines Flags eine Control-Variable nimmt, hätte man das gleiche Problem, weil man in textBox_Enter nicht unterscheiden kann, ob es durch einen Klick oder Tab ausgelöst wurde (das Flag sollte nur dann gesetzt werden, wenn Enter durch einen Klick ausgelöst wurde, weil ich's nur dann im folgenden MausDown-Ereignis prüfen möchte).
Ich könnte nun im textBox_Enter prüfen, ob sich die linke Maustaste im gedrückten Zustand befindet, das wäre aber auch problematisch, weil ja z. B. die Maustaste zum Zeitpunkt der Codeausführung evtl schon wieder losgelossen sein könnte oder womöglich mit Tastaturmaus gearbeitet wird...

Ich sehe also nicht, wie sich dieses Problem lösen lässt. 🤔 Könntest du (oder jemand anders) den obigen Code anpassen, falls ihr etwas anderes meint, als ich verstanden hab?

4.942 Beiträge seit 2008
vor 13 Jahren

Hi,

du willst, daß bei Maus-Klick die Selection aufgehoben wird (wenn sie vorher selektiert war)?
Dann


private void textBox_MouseDown(object sender, MouseEventArgs e)
{
    TextBox textBox = sender as TextBox;
    if(textBox != null)
    {
        if (focusChanged)
        {
            textBox.SelectionLength = 0;
            focusChanged = false;
        }
        else
        {
            textBox.SelectAll();
        }
    }
}

Außerdem solltest du im textBox_Leave wieder das Flag zurücksetzen:


private void textBox_Leave(object sender, EventArgs e)
{
    focusChanged = false;
}

Alternativ dazu einfach im MouseDown den Selection-Status abfragen:


private void textBox_MouseDown(object sender, MouseEventArgs e)
{
    TextBox textBox = sender as TextBox;
    if(textBox != null)
    {
        if (textBox.SelectionLength > 0)
        {
            textBox.SelectionLength = 0;
        }
        else
        {
            textBox.SelectAll();
        }
    }
}

(einfach 'toggeln', d.h. kein Flag mehr nötig 😉

B
14 Beiträge seit 2009
vor 13 Jahren

du willst, daß bei Maus-Klick die Selection aufgehoben wird (wenn sie vorher selektiert war)?

Um das zu erreichen, müsste ich ja keinen Code schreiben, weil sich TextBoxen standardmäßig so verhalten, dass eine Selektion aufgehoben wird, wenn darauf geklickt wird. Ich möchte, dass der Text in einer Textbox markiert wird, sobald sie den Fokus erhält (indem Tab gedrückt wurde oder die TextBox angeklickt wurde, als sie NICHT den Fokus hatte).

Wenn eine Textbox bereits den Fokus hat und der Benutzer darauf klickt, soll nichts passieren (außer dem, was sowieso passier, d. h. Cursor wird umgesetzt).

In allen Fällen, wo eine Textbox fokussiert wird, wird das Enter-Ereignis ausgelöst. Nur im Enter-Ereignis SelectAll aufzurufen reicht allerdings leider nicht, da im Falle eines Klicks die Selektion danach sofort wieder aufgehoben würde (weil das MouseDown erst nach dem Enter ausgeführt wird und bei jedem MouseDown in einer TextBox - sofern man nicht im MouseDown-Event SelectAll aufruft - eine eventuelle Selektion des Textes darin aufgehoben wird). Ich müsste also im Enter-Event ein Flag setzen, aber nur wenn dieses Enter durch Mausklick und nicht durch Tab ausgelöst wurde. Falls das Flag gesetzt ist, rufe ich im MouseDown dann SelectAll auf und setze das Flag wieder zurück. Aber woher kann ich im Enter-Event wissen, ob das Enter durch Tab oder durch Mausklick ausgelöst wurde?

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo BcVcB,

es sollte vollkommen ausreichen, das SelectAll zu verzögern, bis der Fokuswechsel vollständig abgeschlossen ist. Dazu kann man Control.BeginInvoke verwenden (sic!).

protected void TextBoxEnter (Object sender, EventArgs e)
{
   TextBox tbx = (TextBox)sender;
   tbx.BeginInvoke (new MethodInvoker (tbx.SelectAll));
}

herbivore

PS: Siehe dazu auch [FAQ] Bestimmte Aktionen bis nach der laufenden GUI-Event-Behandlung verzögern.

B
14 Beiträge seit 2009
vor 13 Jahren

Danke Herbivore, damit funktioniert es. 😃

16 Beiträge seit 2014
vor 9 Jahren
Hinweis von herbivore vor 9 Jahren

Hobelschlunze meldet: "Habe gemerkt das mein Löschungsvorschlag doch nicht die komplett richtige Lösung ist 😃" Und außerdem stehen weiter oben funktionierende Lösungen bereits.

 
private void textBox1_Enter(object sender, System.EventArgs e){
   if (!String.IsNullOrEmpty(textBox1.Text))
   {
      textBox1.SelectionStart = 0;
      textBox1.SelectionLength = textBox1.Text.Length;
   }
}

oder einfach


private void textBox1_Enter(object sender, System.EventArgs e){
   if (!String.IsNullOrEmpty(textBox1.Text))
   {
      textBox1.SelectAll();
   }
}

Das tuts auch 😃

Azubi im 2ten Lehrjahr (Fachinformatiker Anwendungsentwicklung)

Codieren Sie immer so, als wäre der Typ, der den Code pflegen muss, ein gewaltbereiter Psychopath, der weiß, wo Sie wohnen.

S
145 Beiträge seit 2013
vor 9 Jahren

hier mal ein ausschnitt aus einer meiner abgeleiteten Textboxen:

        protected override void WndProc(ref Message m)
        {
            bool isFocused = this.Focused;

            base.WndProc(ref m);

            if (!isFocused && m.Msg == 0x0201) //WM_LBUTTONDOWN
                OnMouseDownFirst(EventArgs.Empty);
        }

ich hab mir hier allerdings nochmal ein eigenes event MouseDownFirst gemacht welches ich abonniere.
Man könnte da allerdings auch schon direkt SelectAll() aufrufen.

49.485 Beiträge seit 2005
vor 9 Jahren

Hallo Spyke,

es gibt allerdings (weit) mehr Möglichkeiten, wie ein Control den Focus bekommt, als nur durch einen Klick mit der linken Maus. Zum Beispiel über die Tastatur (Tab, Shift-Tab, Shortcut/Accelerator) oder programmtechnisch und bei zukünftigen Eingabegeräten/-möglichkeiten noch ganz (unvoraussehbar) anders.

Daher sollte man immer die passenden Events verwenden, hier also Enter oder sogar noch eher GotFocus.

herbivore

S
145 Beiträge seit 2013
vor 9 Jahren

Das Enter Ereignis beachte ich natürlich auch mit.

Bei meinem Code gings nur noch um das Problem mit dem Mausklick das dort alles selektiert wird und nur wenn vorher noch kein Focus auf der Textbox vorhanden war.

Sry hat ich vergessen mit zu erwähnen.

P.S.: Die Gelbe Schrift ging bissl unter hab auch nicht gemerkt das der Thread schon 8 Jahre oder so alt ist, hatte mich mehr auf die Posts konzentriert.