@fletcher: Nie udało mi się jeszcze na to spojrzeć. Za kilka dni udzielę odpowiedzi.
CJ7
Możesz dodać tag vb.net, ponieważ problem jest naprawdę ten sam, a zaakceptowana odpowiedź jest również ważna
Andrea Antonangeli
Odpowiedź BenSmitha dotycząca przeglądania kolejności zakładek będzie bardzo przydatna w takim scenariuszu.
Samitha Chathuranga,
Odpowiedzi:
129
Pole tekstowe ma TabIndex0 i jest TabStopustawione na true. Oznacza to, że po wyświetleniu formularza fokus zostanie przypisany do kontrolki.
Możesz albo nadać innej kontrolce 0 TabIndex(jeśli istnieje) i nadać polu tekstowemu inny indeks tabulatora (> 0) lub ustawić TabStopna fałsz, aby pole tekstowe to powstrzymało.
Czy na pewno pole tekstowe TabIndex jest ustawione na 0? Wynika z jego zachowania?
26071986
@ 26071986 - Cóż, przeprowadziłem szybki test. Jeśli w formularzu z jednym polem tekstowym i przyciskiem zmienię tekst w polu tekstowym w konstruktorze, gdy tabindex jest ustawiony na 0, tekst jest podświetlony. Jeśli przycisk ma indeks zakładki 0, a indeks tabulacji pola tekstowego jest> 0, tekst nie jest podświetlony.
fletcher
Rzeczywiście wydaje się, że ma to związek z TabIndex - tylko ja odpowiednio zmieniłem indeksy wszystkich moich elementów (tak pomyślałem). Okazuje się, że grupy również mają indeksy tabulatorów, które należy zmienić, a także wszystkie zawierające je elementy. Tak więc, podczas gdy ustawiłem zakładki elementów od 1 do 9, grupa nadal miała 0, więc pole tekstowe w tej grupie stało się pierwszym aktywowanym elementem (stąd jego zawartość została podświetlona).
deed02392
1
Niekoniecznie jest to związane z posiadaniem TabIndex = 0, ale z pewnością dzieje się tak, jeśli TextBox ma NAJNIŻSZY TabIndex formularza. Aby sprawdzić: ustaw TabIndex = 5 w TextBox i ustaw liczbę większą niż 5 we wszystkich TabIndexs innych kontrolek formularza.
Andrea Antonangeli
Dzieje się tak również po wybraniu nowej TabPage w TabControl. To samo rozwiązanie działa.
JonP
44
Domyślnym zachowaniem TextBox w Windows Forms jest podświetlenie całego tekstu, jeśli zostanie on skupiony po raz pierwszy, przechodząc do niego, ale nie, jeśli zostanie kliknięty. Widzimy to w reflektor patrząc na TextBox„s OnGotFocus()ręcznym:
Chodzi o to, że jeśli stwierdzenie powoduje zachowanie, którego nie lubimy. Ponadto, aby dodać zniewagę do obrażeń, Textustawiacz właściwości ślepo resetuje tę selectionSetzmienną za każdym razem, gdy tekst jest ponownie przypisywany:
publicoverridestring Text
{
get
{
returnbase.Text;
}
set
{
base.Text = value;
this.selectionSet = false;
}
}
Więc jeśli masz TextBox i kartę, cały tekst zostanie zaznaczony. Jeśli klikniesz na niego, podświetlenie zostanie usunięte, a jeśli ponownie przejdziesz do niego tabulatorem, pozycja kursora (i długość zaznaczenia równa zero) zostanie zachowana. Ale jeśli programowo ustawimy nowyText i ponownie przejdziemy do TextBox, cały tekst zostanie ponownie zaznaczony.
Jeśli jesteś podobny do mnie i uważasz to zachowanie za irytujące i niespójne, istnieją dwa sposoby obejścia tego problemu.
Pierwszym i prawdopodobnie najłatwiejszym jest po prostu wywołanie ustawienia selectionSetprzez wywołanie DeselectAll()formularza Load()i za każdym razem, gdy Textzmiany:
( DeselectAll()po prostu ustawia SelectionLengthna zero. Właściwie SelectionStartto odwraca zmienną TextBox' selectionSet. W powyższym przypadku wywołanie DeselectAll()nie jest konieczne, ponieważ ustawiamy początek na koniec tekstu. Ale jeśli ustawimy go na inną pozycję, na przykład początek tekstu, a następnie nazwanie go jest dobrym pomysłem).
Bardziej trwałym sposobem jest utworzenie własnego TextBox z pożądanym zachowaniem poprzez dziedziczenie:
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;
}
}
}
Może kusiło Cię, aby po prostu nie dzwonić base.OnGotFocus(), ale wtedy stracilibyśmy użyteczną funkcjonalność w Controlklasie bazowej . I możesz ulec pokusie, aby nie zadzierać zselectionSet bzdurami i po prostu odznaczać tekst za każdym razem w OnGotFocus (), ale wtedy stracilibyśmy wyróżnienie użytkownika, gdyby wyszedł z pola iz powrotem.
Odpowiedzi na to pytanie bardzo mi pomogły w podobnym problemie, ale do prostej odpowiedzi podpowiada tylko wiele innych złożonych sugestii. Wystarczy ustawić SelectionStart, aby 0po ustawieniu tekstu. Problem rozwiązany!
Spowoduje to usunięcie zaznaczenia tekstu, jeśli wcześniej wyostrzyłeś pole tekstowe, zaznaczyłeś jakiś tekst w nim, odsunąłeś się od niego, a następnie ponownie wyostrzyłeś.
Stewart
0
Nie testowałem tego w C #, ale napotkałem ten sam problem przy użyciu okna dialogowego C ++ WIN32. Wygląda na to, że możesz zmienić zachowanie, wracając FALSEzOnInitDialog() lub WM_INITDIALOG. Mam nadzieję że to pomoże.
Odpowiedzi:
Pole tekstowe ma
TabIndex
0 i jestTabStop
ustawione na true. Oznacza to, że po wyświetleniu formularza fokus zostanie przypisany do kontrolki.Możesz albo nadać innej kontrolce 0
TabIndex
(jeśli istnieje) i nadać polu tekstowemu inny indeks tabulatora (> 0) lub ustawićTabStop
na fałsz, aby pole tekstowe to powstrzymało.źródło
Domyślnym zachowaniem TextBox w Windows Forms jest podświetlenie całego tekstu, jeśli zostanie on skupiony po raz pierwszy, przechodząc do niego, ale nie, jeśli zostanie kliknięty. Widzimy to w reflektor patrząc na
TextBox
„sOnGotFocus()
ręcznym: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(); } } }
Chodzi o to, że jeśli stwierdzenie powoduje zachowanie, którego nie lubimy. Ponadto, aby dodać zniewagę do obrażeń,
Text
ustawiacz właściwości ślepo resetuje tęselectionSet
zmienną za każdym razem, gdy tekst jest ponownie przypisywany:public override string Text { get { return base.Text; } set { base.Text = value; this.selectionSet = false; } }
Więc jeśli masz TextBox i kartę, cały tekst zostanie zaznaczony. Jeśli klikniesz na niego, podświetlenie zostanie usunięte, a jeśli ponownie przejdziesz do niego tabulatorem, pozycja kursora (i długość zaznaczenia równa zero) zostanie zachowana. Ale jeśli programowo ustawimy nowy
Text
i ponownie przejdziemy do TextBox, cały tekst zostanie ponownie zaznaczony.Jeśli jesteś podobny do mnie i uważasz to zachowanie za irytujące i niespójne, istnieją dwa sposoby obejścia tego problemu.
Pierwszym i prawdopodobnie najłatwiejszym jest po prostu wywołanie ustawienia
selectionSet
przez wywołanieDeselectAll()
formularzaLoad()
i za każdym razem, gdyText
zmiany:protected override void OnLoad(EventArgs e) { base.OnLoad(e); this.textBox2.SelectionStart = this.textBox2.Text.Length; this.textBox2.DeselectAll(); }
(
DeselectAll()
po prostu ustawiaSelectionLength
na zero. WłaściwieSelectionStart
to odwraca zmiennąTextBox
'selectionSet
. W powyższym przypadku wywołanieDeselectAll()
nie jest konieczne, ponieważ ustawiamy początek na koniec tekstu. Ale jeśli ustawimy go na inną pozycję, na przykład początek tekstu, a następnie nazwanie go jest dobrym pomysłem).Bardziej trwałym sposobem jest utworzenie własnego TextBox z pożądanym zachowaniem poprzez dziedziczenie:
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; } } }
Może kusiło Cię, aby po prostu nie dzwonić
base.OnGotFocus()
, ale wtedy stracilibyśmy użyteczną funkcjonalność wControl
klasie bazowej . I możesz ulec pokusie, aby nie zadzierać zselectionSet
bzdurami i po prostu odznaczać tekst za każdym razem w OnGotFocus (), ale wtedy stracilibyśmy wyróżnienie użytkownika, gdyby wyszedł z pola iz powrotem.Brzydki? Jasne. Ale tak właśnie jest.
źródło
Odpowiedzi na to pytanie bardzo mi pomogły w podobnym problemie, ale do prostej odpowiedzi podpowiada tylko wiele innych złożonych sugestii. Wystarczy ustawić
SelectionStart
, aby0
po ustawieniu tekstu. Problem rozwiązany!Przykład:
yourtextbox.Text = "asdf"; yourtextbox.SelectionStart = 0;
źródło
Możesz również wybrać kolejność zakładek dla kontrolek formularza, otwierając:
Widok-> Kolejność zakładek
Zauważ, że ta opcja jest dostępna tylko w „Widok”, jeśli masz otwarty widok projektu formularza.
Wybranie „Kolejność zakładek” otwiera widok formularza, który pozwala wybrać żądaną kolejność zakładek, klikając kontrolki.
źródło
Aby usunąć podświetlenie pola tekstowego, w VS 2013 spróbuj zainicjować za pomocą:
myTextBox.GotFocus += new System.EventHandler(this.myTextBox_GotFocus);
I dodaj metodę:
public void myTextBox_GotFocus(object sender, EventArgs e) { myTextBox.SelectionLength=0; }
źródło
Nie testowałem tego w C #, ale napotkałem ten sam problem przy użyciu okna dialogowego C ++ WIN32. Wygląda na to, że możesz zmienić zachowanie, wracając
FALSE
zOnInitDialog()
lubWM_INITDIALOG
. Mam nadzieję że to pomoże.źródło