Textbox SelectAll on tab but not mouse click

后端 未结 5 882
情深已故
情深已故 2021-01-07 22:56

So lets say I have a WPF form with several text boxes, if you tab to the text box and it already has something in it, I want to select all the text in that box so typing wil

相关标签:
5条回答
  • 2021-01-07 23:22

    Have not seen any clean solution so far sadly, one thing you could do is just check the mouse state:

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

    But there actually is a better way, as the focus shifts on key down you can check the keyboard instead. I would recommend using the proper signature for the GotKeyboardFocus handler to get the appropriate event-args:

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

    At this point you may still see some selection getting cleared upon click but that is just because the previous selection only gets hidden if unfocused. You can always clear the selection in LostKeyboardFocus to prevent that (e.g. ((TextBox)sender).Select(0, 0)).

    0 讨论(0)
  • 2021-01-07 23:24

    You could capture the last key pressed and compare against it in your event

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

    and in your event:

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

    It's not perfect because they could have hit tab (not tabbing into your control) and than click into it your control. But it will work most of the time.

    0 讨论(0)
  • 2021-01-07 23:30

    You could try checking if the Mouse is present in the TextBox when the Focus Event happens and check the Mouse ButtonButtonState. This is not perfect but should be close to what you are looking for.

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

    and as H.B. Pointed out you could try using the txt.IsMouseOver Property to determine if the Cursor is inside the TextBox's Client Rectangle. It looks a lot cleaner.

    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 讨论(0)
  • 2021-01-07 23:30

    You can use attached behavior pattern

    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 your xaml only need

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

    use you can use in a TextBox like

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

    all this work for mouse and keyboard event

    0 讨论(0)
  • 2021-01-07 23:39

    I searched a lot for the solution, I found couple of solutions to selectall But, the issue is when we do right click and do cut/copy after selecting part of text from text box, it selects all even I selected part of text. To fix this here is the solution. Just add the below code in the keyboard select event. This worked for me.

        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();
        }
    
    0 讨论(0)
提交回复
热议问题