Hast du es geschafft, das zu klären? Wie haben Sie das behoben?
Fletcher
@fletcher: Ich bin noch nicht dazu gekommen, es mir anzusehen. Ich werde die Antwort in ein paar Tagen vergeben.
CJ7
Sie können ein vb.net-Tag hinzufügen, da das Problem wirklich dasselbe ist und die akzeptierte Antwort auch gültig ist
Andrea Antonangeli
Die Antwort von BenSmith in Bezug auf das Anzeigen der Tab-Reihenfolge ist in einem solchen Szenario sehr nützlich.
Samitha Chathuranga
Antworten:
128
Das Textfeld hat eine TabIndex0 und wird TabStopauf true gesetzt. Dies bedeutet, dass das Steuerelement bei der Anzeige des Formulars den Fokus erhält.
Sie können entweder einem anderen Steuerelement die 0 TabIndex(falls vorhanden) zuweisen und dem Textfeld einen anderen Registerkartenindex (> 0) zuweisen oder TabStopfür das Textfeld den Wert false festlegen , um dies zu verhindern.
Sind Sie sicher, dass das Textfeld TabIndex auf 0 gesetzt ist? Es kommt aus seinem Verhalten?
26071986
@ 26071986 - Nun, ich habe einen Schnelltest durchgeführt. Wenn ich in einem Formular mit einem Textfeld und einer Schaltfläche den Text innerhalb des Textfelds im Konstruktor ändere, wenn der Tabindex auf 0 gesetzt ist, wird der Text hervorgehoben. Wenn die Schaltfläche den Index der Registerkarte 0 hat und der Textfeld-Tabindex> 0 ist, wird der Text nicht hervorgehoben.
Fletcher
Es scheint tatsächlich mit TabIndex zu tun zu haben - nur ich habe alle Registerkartenindizes meiner Elemente entsprechend geändert (so dachte ich). Es stellt sich heraus, dass Gruppen auch Registerkartenindizes haben, die Sie ändern müssen, sowie alle ihre enthaltenen Elemente. Während ich Elementregisterkarten von 1 bis 9 eingerichtet hatte, hatte eine Gruppe immer noch 0, sodass das Textfeld in dieser Gruppe das erste aktivierte Element wurde (daher wurde dessen Inhalt hervorgehoben).
deed02392
1
Es hängt nicht unbedingt mit TabIndex = 0 zusammen, aber es kommt sicherlich vor, wenn die TextBox den NIEDRIGSTEN TabIndex des Formulars hat. So überprüfen Sie Folgendes: Setzen Sie in der Textbox TabIndex = 5 und in allen TabIndexs der anderen Steuerelemente des Formulars eine Zahl größer als 5.
Andrea Antonangeli
Dies geschieht auch, wenn Sie eine neue TabPage in einem TabControl auswählen. Die gleiche Lösung funktioniert.
JonP
43
Das Standardverhalten einer TextBox in Windows Forms besteht darin, den gesamten Text hervorzuheben, wenn er zum ersten Mal durch Tippen darauf fokussiert wird, nicht jedoch, wenn darauf geklickt wird. Wir können dies in Reflector sehen Sie in der Suche TextBox‚s OnGotFocus()überschreiben:
Es ist diese if-Anweisung, die das Verhalten verursacht, das wir nicht mögen. Um die Verletzung zusätzlich zu beleidigen, setzt der TextSetter der Eigenschaft diese selectionSetVariable blind zurück, wenn der Text neu zugewiesen wird:
publicoverridestring Text
{
get
{
returnbase.Text;
}
set
{
base.Text = value;
this.selectionSet = false;
}
}
Wenn Sie also eine TextBox und eine Registerkarte haben, wird der gesamte Text ausgewählt. Wenn Sie darauf klicken, wird die Hervorhebung entfernt, und wenn Sie erneut darauf klicken, bleibt Ihre Caret-Position (und die Auswahllänge Null) erhalten. Wenn wir jedoch programmgesteuert neu Textfestlegen und erneut in die TextBox wechseln, wird der gesamte Text erneut ausgewählt.
Wenn Sie wie ich sind und dieses Verhalten als störend und inkonsistent empfinden, gibt es zwei Möglichkeiten, um dieses Problem zu umgehen.
Die erste und wahrscheinlich einfachste Möglichkeit besteht darin, die Einstellung einfach selectionSetdurch Aufrufen DeselectAll()des Formulars Load()und bei jeder TextÄnderung auszulösen :
( DeselectAll()setzt nur SelectionLengthauf Null. SelectionStartTatsächlich wird die Variable von TextBox' selectionSetumgedreht. Im obigen Fall ist der Aufruf von DeselectAll()nicht erforderlich, da wir den Anfang bis zum Ende des Textes setzen. Aber wenn wir ihn auf eine andere Position setzen, wie z Es ist eine gute Idee, den Anfang des Textes zu beginnen und ihn dann aufzurufen.)
Der dauerhaftere Weg besteht darin, eine eigene TextBox mit dem gewünschten Verhalten durch Vererbung zu erstellen:
publicclassNonSelectingTextBox : TextBox
{
// Base class has a selectionSet property, but its private.// We need to shadow with our own variable. If true, this means// "don't mess with the selection, the user did it."privatebool selectionSet;
protectedoverridevoidOnGotFocus(EventArgs e)
{
bool needToDeselect = false;
// We don't want to avoid calling the base implementation// completely. We mirror the logic that we are trying to avoid;// if the base implementation will select all of the text, we// set a boolean.if (!this.selectionSet)
{
this.selectionSet = true;
if ((this.SelectionLength == 0) &&
(Control.MouseButtons == MouseButtons.None))
{
needToDeselect = true;
}
}
// Call the base implementationbase.OnGotFocus(e);
// Did we notice that the text was selected automatically? Let's// de-select it and put the caret at the end.if (needToDeselect)
{
this.SelectionStart = this.Text.Length;
this.DeselectAll();
}
}
publicoverridestring Text
{
get
{
returnbase.Text;
}
set
{
base.Text = value;
// Update our copy of the variable since the// base implementation will have flipped its back.this.selectionSet = false;
}
}
}
Sie könnten versucht sein, einfach nicht anzurufen base.OnGotFocus(), aber dann würden wir nützliche Funktionen in der Basisklasse verlieren Control. Und Sie könnten versucht sein, sich überhaupt nicht mit dem selectionSetUnsinn herumzuschlagen und den Text jedes Mal in OnGotFocus () abzuwählen, aber dann würden wir die Hervorhebung des Benutzers verlieren, wenn er aus dem Feld und zurück wechselt.
Hässlich? Darauf kannst du wetten. Aber es ist was es ist.
Die Antworten auf diese Frage haben mir bei einem ähnlichen Problem sehr geholfen, aber die einfache Antwort wird nur mit vielen anderen komplexen Vorschlägen angedeutet. Einfach einstellenSelectionStart , 0nachdem Sie Ihren Text eingestellt haben. Problem gelöst!
Sie können auch die Tabulatorreihenfolge für die Steuerelemente Ihres Formulars auswählen, indem Sie Folgendes öffnen:
Ansicht-> Tab-Reihenfolge
Beachten Sie, dass diese Option in "Ansicht" nur verfügbar ist, wenn Sie die Formularentwurfsansicht geöffnet haben.
Durch Auswahl von "Tab-Reihenfolge" wird eine Ansicht des Formulars geöffnet, in der Sie die gewünschte Tab-Reihenfolge auswählen können, indem Sie auf die Steuerelemente klicken.
Dies würde dazu führen, dass die Auswahl des Texts aufgehoben wird, wenn Sie zuvor das Textfeld fokussiert, Text darin ausgewählt, von ihm entfernt und dann erneut fokussiert haben.
Stewart
0
Ich habe dies nicht auf C # getestet, aber ich bin über ein C ++ WIN32-Dialogfeld auf dasselbe Problem gestoßen. Es scheint, als könnten Sie das Verhalten ändern, indem Sie FALSEvon OnInitDialog()oder zurückkehren WM_INITDIALOG. Hoffe das hilft.
Antworten:
Das Textfeld hat eine
TabIndex
0 und wirdTabStop
auf true gesetzt. Dies bedeutet, dass das Steuerelement bei der Anzeige des Formulars den Fokus erhält.Sie können entweder einem anderen Steuerelement die 0
TabIndex
(falls vorhanden) zuweisen und dem Textfeld einen anderen Registerkartenindex (> 0) zuweisen oderTabStop
für das Textfeld den Wert false festlegen , um dies zu verhindern.quelle
Das Standardverhalten einer TextBox in Windows Forms besteht darin, den gesamten Text hervorzuheben, wenn er zum ersten Mal durch Tippen darauf fokussiert wird, nicht jedoch, wenn darauf geklickt wird. Wir können dies in Reflector sehen Sie in der Suche
TextBox
‚sOnGotFocus()
überschreiben:protected override void OnGotFocus(EventArgs e) { base.OnGotFocus(e); if (!this.selectionSet) { this.selectionSet = true; if ((this.SelectionLength == 0) && (Control.MouseButtons == MouseButtons.None)) { base.SelectAll(); } } }
Es ist diese if-Anweisung, die das Verhalten verursacht, das wir nicht mögen. Um die Verletzung zusätzlich zu beleidigen, setzt der
Text
Setter der Eigenschaft dieseselectionSet
Variable blind zurück, wenn der Text neu zugewiesen wird:public override string Text { get { return base.Text; } set { base.Text = value; this.selectionSet = false; } }
Wenn Sie also eine TextBox und eine Registerkarte haben, wird der gesamte Text ausgewählt. Wenn Sie darauf klicken, wird die Hervorhebung entfernt, und wenn Sie erneut darauf klicken, bleibt Ihre Caret-Position (und die Auswahllänge Null) erhalten. Wenn wir jedoch programmgesteuert neu
Text
festlegen und erneut in die TextBox wechseln, wird der gesamte Text erneut ausgewählt.Wenn Sie wie ich sind und dieses Verhalten als störend und inkonsistent empfinden, gibt es zwei Möglichkeiten, um dieses Problem zu umgehen.
Die erste und wahrscheinlich einfachste Möglichkeit besteht darin, die Einstellung einfach
selectionSet
durch AufrufenDeselectAll()
des FormularsLoad()
und bei jederText
Änderung auszulösen :protected override void OnLoad(EventArgs e) { base.OnLoad(e); this.textBox2.SelectionStart = this.textBox2.Text.Length; this.textBox2.DeselectAll(); }
(
DeselectAll()
setzt nurSelectionLength
auf Null.SelectionStart
Tatsächlich wird die Variable vonTextBox
'selectionSet
umgedreht. Im obigen Fall ist der Aufruf vonDeselectAll()
nicht erforderlich, da wir den Anfang bis zum Ende des Textes setzen. Aber wenn wir ihn auf eine andere Position setzen, wie z Es ist eine gute Idee, den Anfang des Textes zu beginnen und ihn dann aufzurufen.)Der dauerhaftere Weg besteht darin, eine eigene TextBox mit dem gewünschten Verhalten durch Vererbung zu erstellen:
public class NonSelectingTextBox : TextBox { // Base class has a selectionSet property, but its private. // We need to shadow with our own variable. If true, this means // "don't mess with the selection, the user did it." private bool selectionSet; protected override void OnGotFocus(EventArgs e) { bool needToDeselect = false; // We don't want to avoid calling the base implementation // completely. We mirror the logic that we are trying to avoid; // if the base implementation will select all of the text, we // set a boolean. if (!this.selectionSet) { this.selectionSet = true; if ((this.SelectionLength == 0) && (Control.MouseButtons == MouseButtons.None)) { needToDeselect = true; } } // Call the base implementation base.OnGotFocus(e); // Did we notice that the text was selected automatically? Let's // de-select it and put the caret at the end. if (needToDeselect) { this.SelectionStart = this.Text.Length; this.DeselectAll(); } } public override string Text { get { return base.Text; } set { base.Text = value; // Update our copy of the variable since the // base implementation will have flipped its back. this.selectionSet = false; } } }
Sie könnten versucht sein, einfach nicht anzurufen
base.OnGotFocus()
, aber dann würden wir nützliche Funktionen in der Basisklasse verlierenControl
. Und Sie könnten versucht sein, sich überhaupt nicht mit demselectionSet
Unsinn herumzuschlagen und den Text jedes Mal in OnGotFocus () abzuwählen, aber dann würden wir die Hervorhebung des Benutzers verlieren, wenn er aus dem Feld und zurück wechselt.Hässlich? Darauf kannst du wetten. Aber es ist was es ist.
quelle
Die Antworten auf diese Frage haben mir bei einem ähnlichen Problem sehr geholfen, aber die einfache Antwort wird nur mit vielen anderen komplexen Vorschlägen angedeutet. Einfach einstellen
SelectionStart
,0
nachdem Sie Ihren Text eingestellt haben. Problem gelöst!Beispiel:
yourtextbox.Text = "asdf"; yourtextbox.SelectionStart = 0;
quelle
Sie können auch die Tabulatorreihenfolge für die Steuerelemente Ihres Formulars auswählen, indem Sie Folgendes öffnen:
Ansicht-> Tab-Reihenfolge
Beachten Sie, dass diese Option in "Ansicht" nur verfügbar ist, wenn Sie die Formularentwurfsansicht geöffnet haben.
Durch Auswahl von "Tab-Reihenfolge" wird eine Ansicht des Formulars geöffnet, in der Sie die gewünschte Tab-Reihenfolge auswählen können, indem Sie auf die Steuerelemente klicken.
quelle
Um ein Textfeld in VS 2013 hervorzuheben, versuchen Sie init mit:
myTextBox.GotFocus += new System.EventHandler(this.myTextBox_GotFocus);
Und fügen Sie die Methode hinzu:
public void myTextBox_GotFocus(object sender, EventArgs e) { myTextBox.SelectionLength=0; }
quelle
Ich habe dies nicht auf C # getestet, aber ich bin über ein C ++ WIN32-Dialogfeld auf dasselbe Problem gestoßen. Es scheint, als könnten Sie das Verhalten ändern, indem Sie
FALSE
vonOnInitDialog()
oder zurückkehrenWM_INITDIALOG
. Hoffe das hilft.quelle