2012-08-02 20 views
15

Also sagen wir, ich habe ein WPF-Formular mit mehreren Textfeldern, wenn Sie Tab auf das Textfeld und es hat bereits etwas, ich möchte den gesamten Text in diesem Feld so auswählen Das Tippen löscht diesen Text. Wenn Sie mit der Maus auf das Feld klicken, bedeutet das wahrscheinlich, dass Sie einen Buchstaben irgendwo ändern möchten. Markieren Sie in diesem Fall also nicht alle Buchstaben. Scheint einfach, aber eine gute Lösung, wie mir bisher entgangen ist. Hier ist, was ich bisher habe, ist sehr schließen zu arbeiten, aber nicht ganz perfekt.Textbox SelectAll auf Registerkarte, aber nicht Mausklick

<Style x:Key="TextBoxStyle" TargetType="TextBox"> 
    <EventSetter Event="GotKeyboardFocus" Handler="EventSetter_OnHandler" /> 
</Style> 

private void EventSetter_OnHandler(object sender, RoutedEventArgs e) 
{ 
    TextBox txt = sender as TextBox; 
    if (txt != null) txt.SelectAll(); 
} 

Also, wenn die Box wählt Tastatur den Fokus erhält es alle, so in das Textfeld Tabbing wählt den gesamten Text perfekt. Bei Mausklicks wird jedoch auch diese Methode aufgerufen, die auch den Text hervorhebt, aber der Klick bringt den Cursor dann dorthin, wo die Maus geklickt hat. So funktional ist es perfekt, aber es stört mich immer noch, dass es flackert, alles auszuwählen, wenn die Maus klickt. Gibt es einen besseren Weg, dies zu tun, oder eine Art Check in meinem Event durchzuführen, um zu wissen, dass ich den Tastaturfokus durch einen Mausklick und nicht durch einen Tab gewonnen habe?

Antwort

19

hat keine saubere Lösung bisher leider ist eine Sache gesehen man tun könnte nur den Zustand Maus überprüfen:

var tb = (TextBox)sender; 
if (Mouse.LeftButton != MouseButtonState.Pressed) 
    tb.SelectAll(); 

Aber es ist eigentlich eine bessere Art und Weise, wie die Fokusverschiebungen auf Taste nach unten können Sie Überprüfen Sie stattdessen die Tastatur. Ich würde mit der richtigen Signatur für den GotKeyboardFocus Handler empfehlen die entsprechenden Ereignis-args zu erhalten:

private void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) 
{ 
    if (e.KeyboardDevice.IsKeyDown(Key.Tab)) 
     ((TextBox)sender).SelectAll(); 
} 

An dieser Stelle können Sie noch einige Auswahl sehen können auf Klick gelöscht zu werden, aber das ist nur, weil die vorherige Auswahl nur versteckt wird wenn nicht fokussiert. Sie können die Auswahl immer in LostKeyboardFocus löschen, um dies zu verhindern (z. B. ((TextBox)sender).Select(0, 0)).

+0

@KDiTraglia: Ich habe gehofft, dass der 'e.Device' auch ein' MouseDevice' sein könnte, aber wie der Name des args nur Tastatur-es schon sagt, (ist e.Device Keyboard) ein 'wenn 'Check wäre schön gewesen. –

+0

Aber was ist, wenn sie den Textkasten mit der Maus fokussieren, während sie den Tab halten! –

+0

@KDiTraglia: Ich bezweifle, dass jemals passieren wird, wenn Sie Tab der Fokus Zyklen die ganze Zeit halten. –

0

Sie konnte erfassen die letzte Taste gedrückt und vergleichen Sie dagegen in Ihren Event

private Key lastKey; 
protected override void OnKeyDown(KeyEventArgs e) 
{ 
    lastKey = e.Key; 
    base.OnKeyDown(e); 
} 

und in Ihrem Fall:

private void EventSetter_OnHandler(object sender, RoutedEventArgs e) 
{ 
    if(lastKey != Key.Tab) 
     return; 

    TextBox txt = sender as TextBox; 
    if (txt != null) txt.SelectAll(); 
} 

Es ist nicht perfekt, weil sie Tab getroffen haben könnte (nicht Tabbed in Ihre Kontrolle) und klicken Sie dann auf Ihre Kontrolle. Aber es wird die meiste Zeit funktionieren.

1

Sie könnten versuchen, zu überprüfen, ob die Maus in der TextBox vorhanden ist, wenn das Fokusereignis eintritt und überprüfen Sie die Maus ButtonButtonState. Dies ist nicht perfekt, aber sollte in der Nähe sein, was Sie suchen.

private void EventSetter_OnHandler(object sender, RoutedEventArgs e) 
{ 
    TextBox txt = sender as TextBox; 
    Point position = Mouse.GetPosition(txt); 
    // if Mouse position is not in the TextBox Client Rectangle 
    // and Mouse Button not Pressed. 
    if((!(new Rect(0,0,txt.Width,txt.Height)).Contains(position)) || (Mouse.LeftButton != MouseButtonState.Pressed)) 
     if (txt != null) txt.SelectAll(); 
} 

und als H.B. Aufgezeigt, könnten Sie versuchen, die txt.IsMouseOver-Eigenschaft zu verwenden, um festzustellen, ob sich der Cursor im Client-Rechteck der TextBox befindet. Es sieht viel sauberer aus.

private void EventSetter_OnHandler(object sender, RoutedEventArgs e) 
{ 
    TextBox txt = sender as TextBox; 
    if(!txt.IsMouseOver || Mouse.LeftButton != MouseButtonState.Pressed) 
     if (txt != null) txt.SelectAll(); 
} 
+0

Übrigens gibt es eine Eigenschaft 'UIElement.IsMouseOver'. –

+0

@H.B. Danke für die Erinnerung, ich dachte, es gäbe einen einfacheren Weg. –

0

können Sie angebracht verwenden Verhaltensmuster

public class Behaviors 
{ 
    public static readonly DependencyProperty SelectTextOnFocusProperty = DependencyProperty 
     .RegisterAttached("SelectTextOnFocus", typeof(bool), typeof(Behaviors), new FrameworkPropertyMetadata(false, GotFocus)); 

    public static void SetSelectTextOnFocus(DependencyObject obj, bool value) 
    { 
     obj.SetValue(SelectTextOnFocusProperty, value); 
    } 

    private static void GotFocus(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var textbox = d as TextBox; 

     if (null == textbox) return; 

     textbox.GotKeyboardFocus += SelectTextOnFocus; 
     textbox.GotMouseCapture += SelectTextOnFocus; 
    } 

    private static void SelectTextOnFocus(object sender, RoutedEventArgs e) 
    { 
     if (!(sender is TextBox)) return; 
     ((TextBox)sender).SelectAll(); 
    } 
} 

in XAML brauchen nur

xmlns:my="clr-namespace:Namespace;assembly=Rkmax" 

Verwendung Sie in einem Text wie

<TextBox my:Behaviors.SelectTextOnFocus="True" /> 

all dieser Arbeit verwenden können für Maus- und Tastaturereignis

+0

Dies würde alles auswählen, wenn Sie mit der Maus auswählen, was ich nicht möchte. –

+0

Wenn Sie die Auswahl mit der Maus nicht möchten, können Sie die Zeile 'textbox.GotMouseCapture + = SelectTextOnFocus;' – rkmax

+0

Ja, aber dann endet es die gleiche Situation (Klicken mit der Maus verursacht GOTKeyboardFocus zu feuern) –

0

Ich suchte viel nach der Lösung, ich fand paar Lösungen zu selectall Aber das Problem ist, wenn wir rechts klicken und schneiden/kopieren nach der Auswahl eines Teils des Textes aus Textfeld, es wählt alle auch ich ausgewählt Teil des Textes. Um das hier zu beheben, ist die Lösung. Fügen Sie einfach den folgenden Code in das Tastaturauswahl-Ereignis ein. Das hat für mich funktioniert.

private static void SelectContentsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     if (d is TextBox) 
     { 
      TextBox textBox = d as TextBox; 
      if ((e.NewValue as bool?).GetValueOrDefault(false)) 
      { 
       textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;     
      } 
      else 
      { 
       textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText; 

      } 
     } 
    } 


    private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e) 
    { 
     if (e.KeyboardDevice.IsKeyDown(Key.Tab)) 
      ((TextBox)sender).SelectAll(); 
    } 
Verwandte Themen