首页 文章

如何在WPF TextBox中自动选择焦点上的所有文本?

提问于
浏览
197

如果我从 GotFocus 事件处理程序调用 SelectAll ,它对鼠标不起作用 - 一旦释放鼠标,选择就会消失 .

编辑:人们都喜欢Donnelle的回答,我会试着解释为什么我不喜欢它和接受的答案一样多 .

  • 它更复杂,而接受的答案以更简单的方式做同样的事情 .

  • 接受答案的可用性更好 . 当您单击文本中间时,释放鼠标时文本将被取消选中,允许您立即开始编辑,如果您仍想选择全部,只需再次按下按钮,这次它将不会在发布时取消选择 . 按照Donelle的配方,如果我在文本中间单击,我必须单击第二次才能编辑 . 如果我单击文本中的某个位置而不是文本外部,这很可能意味着我想开始编辑而不是覆盖所有内容 .

28 回答

  • 1

    尝试将它放在构造函数中,无论控制文本框是什么:

    Loaded += (sender, e) =>
    {
        MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
        myTextBox.SelectAll();
    }
    
  • 0

    这是迄今为止最简单的解决方案 .

    将全局处理程序添加到应用程序(App.xaml.cs)并完成 . 您只需要几行代码 .

    protected override void OnStartup(StartupEventArgs e)
    {
        EventManager.RegisterClassHandler(typeof(TextBox),
            TextBox.GotFocusEvent,
            new RoutedEventHandler(TextBox_GotFocus));
    
        base.OnStartup(e);
    }
    

    因此,使用EventManager类为类型(TextBox)注册全局事件处理程序 . 实际的处理程序很简单:

    private void TextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        (sender as TextBox).SelectAll();
    }
    

    点击这里:WPF TextBox SelectAll on Focus

    希望能帮助到你 .

  • 1

    不知道为什么它在GotFocus事件中失去了选择 .

    但一种解决方案是在GotKeyboardFocus和GotMouseCapture事件上进行选择 . 这样它总能奏效 .

  • 3

    我们有它所以第一次点击选择全部,另一次点击进入光标(我们的应用程序设计用于带有笔的平板电脑) .

    你可能会发现它很有用 .

    public class ClickSelectTextBox : TextBox
    {
        public ClickSelectTextBox()
        {
            AddHandler(PreviewMouseLeftButtonDownEvent, 
              new MouseButtonEventHandler(SelectivelyIgnoreMouseButton), true);
            AddHandler(GotKeyboardFocusEvent, 
              new RoutedEventHandler(SelectAllText), true);
            AddHandler(MouseDoubleClickEvent, 
              new RoutedEventHandler(SelectAllText), true);
        }
    
        private static void SelectivelyIgnoreMouseButton(object sender, 
                                                         MouseButtonEventArgs e)
        {
            // Find the TextBox
            DependencyObject parent = e.OriginalSource as UIElement;
            while (parent != null && !(parent is TextBox))
                parent = VisualTreeHelper.GetParent(parent);
    
            if (parent != null)
            {
                var textBox = (TextBox)parent;
                if (!textBox.IsKeyboardFocusWithin)
                {
                    // If the text box is not yet focussed, give it the focus and
                    // stop further processing of this click event.
                    textBox.Focus();
                    e.Handled = true;
                }
            }
        }
    
        private static void SelectAllText(object sender, RoutedEventArgs e)
        {
            var textBox = e.OriginalSource as TextBox;
            if (textBox != null)
                textBox.SelectAll();
        }
    }
    
  • 1

    Donnelle的答案效果最好,但是必须派出一个新课程才能使用它是一种痛苦 .

    而不是这样做我在App.xaml.cs中为处理程序中的处理程序注册了应用程序中的所有TextBox . 这允许我使用标准TextBox控件的Donnelle答案 .

    将以下方法添加到App.xaml.cs:

    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e) 
        {
            // Select the text in a TextBox when it receives focus.
            EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseLeftButtonDownEvent,
                new MouseButtonEventHandler(SelectivelyIgnoreMouseButton));
            EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotKeyboardFocusEvent, 
                new RoutedEventHandler(SelectAllText));
            EventManager.RegisterClassHandler(typeof(TextBox), TextBox.MouseDoubleClickEvent,
                new RoutedEventHandler(SelectAllText));
            base.OnStartup(e); 
        }
    
        void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
        {
            // Find the TextBox
            DependencyObject parent = e.OriginalSource as UIElement;
            while (parent != null && !(parent is TextBox))
                parent = VisualTreeHelper.GetParent(parent);
    
            if (parent != null)
            {
                var textBox = (TextBox)parent;
                if (!textBox.IsKeyboardFocusWithin)
                {
                    // If the text box is not yet focused, give it the focus and
                    // stop further processing of this click event.
                    textBox.Focus();
                    e.Handled = true;
                }
            }
        }
    
        void SelectAllText(object sender, RoutedEventArgs e)
        {
            var textBox = e.OriginalSource as TextBox;
            if (textBox != null)
                textBox.SelectAll();
        }
    }
    
  • 4

    这是相当古老的,但无论如何我都会展示我的答案 .
    我选择了部分Donnelle 's answer (skipped the double-click) for I think this creates the least astonishment in the users. However, like gcores I dislike the need to create a derived class. But I also don' t像gcores "on Startup..."方法 . 而且我需要这个_b20710_basis .

    我已将此实现为附加依赖项属性,因此我可以在xaml中设置 SelectTextOnFocus.Active=True . 我发现这种方式最令人愉悦 .

    namespace foo.styles.behaviour
    {
        using System.Windows;
        using System.Windows.Controls;
        using System.Windows.Input;
        using System.Windows.Media;
    
        public class SelectTextOnFocus : DependencyObject
        {
            public static readonly DependencyProperty ActiveProperty = DependencyProperty.RegisterAttached(
                "Active",
                typeof(bool),
                typeof(SelectTextOnFocus),
                new PropertyMetadata(false, ActivePropertyChanged));
    
            private static void ActivePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                if (d is TextBox)
                {
                    TextBox textBox = d as TextBox;
                    if ((e.NewValue as bool?).GetValueOrDefault(false))
                    {
                        textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;
                        textBox.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
                    }
                    else
                    {
                        textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;
                        textBox.PreviewMouseLeftButtonDown -= OnMouseLeftButtonDown;
                    }
                }
            }
    
            private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                DependencyObject dependencyObject = GetParentFromVisualTree(e.OriginalSource);
    
                if (dependencyObject == null)
                {
                    return;
                }
    
                var textBox = (TextBox)dependencyObject;
                if (!textBox.IsKeyboardFocusWithin)
                {
                    textBox.Focus();
                    e.Handled = true;
                }
            }
    
            private static DependencyObject GetParentFromVisualTree(object source)
            {
                DependencyObject parent = source as UIElement;
                while (parent != null && !(parent is TextBox))
                {
                    parent = VisualTreeHelper.GetParent(parent);
                }
    
                return parent;
            }
    
            private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
            {
                TextBox textBox = e.OriginalSource as TextBox;
                if (textBox != null)
                {
                    textBox.SelectAll();
                }
            }
    
            [AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
            [AttachedPropertyBrowsableForType(typeof(TextBox))]
            public static bool GetActive(DependencyObject @object)
            {
                return (bool) @object.GetValue(ActiveProperty);
            }
    
            public static void SetActive(DependencyObject @object, bool value)
            {
                @object.SetValue(ActiveProperty, value);
            }
        }
    }
    

    对于我的“一般但不总是”特征,我在(全局)TextBox-Style中将此属性设置为True . 这种方式“选择文本”总是“打开”,但我可以在每个文本框的基础上禁用它 .

  • 0

    以下是实现答案解决方案的Blend行为,以方便您:

    一个用于附加到单个TextBox:

    public class SelectAllTextOnFocusBehavior : Behavior<TextBox>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.GotKeyboardFocus += AssociatedObjectGotKeyboardFocus;
            AssociatedObject.GotMouseCapture += AssociatedObjectGotMouseCapture;
            AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObjectPreviewMouseLeftButtonDown;
        }
    
        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.GotKeyboardFocus -= AssociatedObjectGotKeyboardFocus;
            AssociatedObject.GotMouseCapture -= AssociatedObjectGotMouseCapture;
            AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObjectPreviewMouseLeftButtonDown;
        }
    
        private void AssociatedObjectGotKeyboardFocus(object sender,
            System.Windows.Input.KeyboardFocusChangedEventArgs e)
        {
            AssociatedObject.SelectAll();
        }
    
        private void AssociatedObjectGotMouseCapture(object sender,
            System.Windows.Input.MouseEventArgs e)
        {
            AssociatedObject.SelectAll();   
        }
    
        private void AssociatedObjectPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if(!AssociatedObject.IsKeyboardFocusWithin)
            {
                AssociatedObject.Focus();
                e.Handled = true;
            }
        }
    }
    

    一个用于附加到包含多个TextBox'es的容器的根目录:

    public class SelectAllTextOnFocusMultiBehavior : Behavior<UIElement>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.GotKeyboardFocus += HandleKeyboardFocus;
            AssociatedObject.GotMouseCapture += HandleMouseCapture;
        }
    
        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.GotKeyboardFocus -= HandleKeyboardFocus;
            AssociatedObject.GotMouseCapture -= HandleMouseCapture;
        }
    
        private static void HandleKeyboardFocus(object sender,
            System.Windows.Input.KeyboardFocusChangedEventArgs e)
        {
            var txt = e.NewFocus as TextBox;
            if (txt != null)
                txt.SelectAll();
        }
    
        private static void HandleMouseCapture(object sender,
            System.Windows.Input.MouseEventArgs e)
        {
            var txt = e.OriginalSource as TextBox;
            if (txt != null)
                txt.SelectAll();
        }
    }
    
  • 1

    这是MSDN上一个非常好的非常简单的解决方案:

    <TextBox
        MouseDoubleClick="SelectAddress"
        GotKeyboardFocus="SelectAddress"
        PreviewMouseLeftButtonDown="SelectivelyIgnoreMouseButton" />
    

    这是背后的代码:

    private void SelectAddress(object sender, RoutedEventArgs e)
    {
        TextBox tb = (sender as TextBox);
        if (tb != null)
        {
            tb.SelectAll();
        }
    }
    
    private void SelectivelyIgnoreMouseButton(object sender,
        MouseButtonEventArgs e)
    {
        TextBox tb = (sender as TextBox);
        if (tb != null)
        {
            if (!tb.IsKeyboardFocusWithin)
            {
                e.Handled = true;
                tb.Focus();
            }
        }
    }
    
  • 194

    虽然这是一个老问题,但我刚刚遇到了这个问题但是使用附加行为解决了它,而不是表达行为,因为谢尔盖's answer. This means I don't需要依赖于混合SDK中的 System.Windows.Interactivity

    public class TextBoxBehavior
    {
        public static bool GetSelectAllTextOnFocus(TextBox textBox)
        {
            return (bool)textBox.GetValue(SelectAllTextOnFocusProperty);
        }
    
        public static void SetSelectAllTextOnFocus(TextBox textBox, bool value)
        {
            textBox.SetValue(SelectAllTextOnFocusProperty, value);
        }
    
        public static readonly DependencyProperty SelectAllTextOnFocusProperty =
            DependencyProperty.RegisterAttached(
                "SelectAllTextOnFocus",
                typeof (bool),
                typeof (TextBoxBehavior),
                new UIPropertyMetadata(false, OnSelectAllTextOnFocusChanged));
    
        private static void OnSelectAllTextOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var textBox = d as TextBox;
            if (textBox == null) return;
    
            if (e.NewValue is bool == false) return;
    
            if ((bool) e.NewValue)
            {
                textBox.GotFocus += SelectAll;
                textBox.PreviewMouseDown += IgnoreMouseButton;
            }
            else
            {
                textBox.GotFocus -= SelectAll;
                textBox.PreviewMouseDown -= IgnoreMouseButton;
            }
        }
    
        private static void SelectAll(object sender, RoutedEventArgs e)
        {
            var textBox = e.OriginalSource as TextBox;
            if (textBox == null) return;
            textBox.SelectAll();
        }
    
        private static void IgnoreMouseButton(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            var textBox = sender as TextBox;
            if (textBox == null || textBox.IsKeyboardFocusWithin) return;
    
            e.Handled = true;
            textBox.Focus();
        }
    }
    

    然后,您可以在XAML中使用它,如下所示:

    <TextBox Text="Some Text" behaviors:TextBoxBehavior.SelectAllTextOnFocus="True"/>
    

    我在博客上写了这篇文章here .

  • 12

    这似乎对我有用 . 这基本上是对一些早期帖子的回顾 . 我只是将它放入构造函数中的MainWindow.xaml.cs文件中 . 我创建了两个处理程序,一个用于键盘,一个用于鼠标,并将两个事件汇集到同一个函数 HandleGotFocusEvent 中,该函数在同一文件中的构造函数之后定义 .

    public MainWindow()
    {
       InitializeComponent();
    
       EventManager.RegisterClassHandler(typeof(TextBox), 
          UIElement.GotKeyboardFocusEvent,
          new RoutedEventHandler(HandleGotFocusEvent), true);
       EventManager.RegisterClassHandler(typeof(TextBox),
          UIElement.GotMouseCaptureEvent,
          new RoutedEventHandler(HandleGotFocusEvent), true);   
    }
    private void HandleGotFocusEvent(object sender, RoutedEventArgs e)
    {
       if (sender is TextBox)
          (sender as TextBox).SelectAll();
    }
    
  • 5

    我认为这很有效:

    private void ValueText_GotFocus(object sender, RoutedEventArgs e)
        {
            TextBox tb = (TextBox)e.OriginalSource;
            tb.Dispatcher.BeginInvoke(
                new Action(delegate
                    {
                        tb.SelectAll();
                    }), System.Windows.Threading.DispatcherPriority.Input);
        }
    

    如果您想将其实现为扩展方法:

    public static void SelectAllText(this System.Windows.Controls.TextBox tb)
        {
            tb.Dispatcher.BeginInvoke(
                new Action(delegate
                {
                    tb.SelectAll();
                }), System.Windows.Threading.DispatcherPriority.Input);
        }
    

    在你的GotFocus活动中:

    private void ValueText_GotFocus(object sender, RoutedEventArgs e)
        {
            TextBox tb = (TextBox)e.OriginalSource;
            tb.SelectAllText();
        }
    

    我发现了上面的解决方案,因为几个月前我一直在寻找一种方法来将焦点设置为给定的UIElement . 我在某处发现了下面的代码(特此授予)并且效果很好 . 我发布它即使它与OP的问题没有直接关系,因为它演示了使用Dispatcher处理UIElement的相同模式 .

    // Sets focus to uiElement
        public static void DelayedFocus(this UIElement uiElement)
        {
            uiElement.Dispatcher.BeginInvoke(
            new Action(delegate
            {
                uiElement.Focusable = true;
                uiElement.Focus();
                Keyboard.Focus(uiElement);
            }),
            DispatcherPriority.Render);
        }
    
  • 147

    我发现这里提到的答案都没有模仿标准的Windows文本框 . 例如,尝试单击文本框的最后一个字符和文本框右侧之间的空白区域 . 这里的大多数解决方案将始终选择整个内容,这使得将文本附加到文本框非常困难 .

    我在这里提出的答案在这方面表现得更好 . 这是一种行为(因此需要来自Blend SDK的System.Windows.Interactivity程序集) . 它也可以使用附加属性重写 .

    public sealed class SelectAllTextOnFocusBehavior : Behavior<TextBox>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObject_PreviewMouseLeftButtonDown;
        }
    
        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObject_PreviewMouseLeftButtonDown;
        }
    
        void AssociatedObject_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // Find the textbox
            DependencyObject parent = e.OriginalSource as UIElement;
            while (parent != null && !(parent is TextBox))
                parent = VisualTreeHelper.GetParent(parent);
    
            var textBox = parent as TextBox;
            Debug.Assert(textBox != null);
    
            if (textBox.IsFocused) return;
    
            textBox.SelectAll();
            Keyboard.Focus(textBox);
            e.Handled = true;
        }
    }
    

    这是基于我发现here的代码 .

  • 68

    在App.xaml文件中

    <Application.Resources>
        <Style TargetType="TextBox">
            <EventSetter Event="GotKeyboardFocus" Handler="TextBox_GotKeyboardFocus"/>
        </Style>
    </Application.Resources>
    

    在App.xaml.cs文件中

    private void TextBox_GotKeyboardFocus(Object sender, KeyboardFocusChangedEventArgs e)
        {
            ((TextBox)sender).SelectAll();
        }
    

    使用此代码,您可以访问应用程序中的所有TextBox .

  • 1

    这个简单的实现非常适合我:

    void TextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        ((TextBox) sender).SelectAll();
    }
    
    void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        var TextBox = (TextBox) sender;
        if (!TextBox.IsKeyboardFocusWithin)
        {
            TextBox.Focus();
            e.Handled = true;
        }
    }
    

    要将其应用于所有 TextBox ,请在 InitializeComponent(); 之后输入以下代码

    EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotFocusEvent, new RoutedEventHandler(TextBox_GotFocus));
    EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseDownEvent, new MouseButtonEventHandler(TextBox_PreviewMouseDown));
    
  • 0

    摘自here

    在App.xaml.cs文件中注册全局事件处理程序:

    protected override void OnStartup(StartupEventArgs e)
    {
        EventManager.RegisterClassHandler(typeof(TextBox),TextBox.GotFocusEvent,
        new RoutedEventHandler(TextBox_GotFocus));
    
        base.OnStartup(e);
    }
    

    然后处理程序就像这样简单:

    private void TextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        (sender as TextBox).SelectAll();
    }
    
  • 0

    我有一个稍微简化的答案(仅使用PreviewMouseLeftButtonDown事件),它似乎模仿了浏览器的常用功能:

    在xaml中你有一个文本框说:

    <TextBox Text="http://www.blabla.com" BorderThickness="2" BorderBrush="Green" VerticalAlignment="Center" Height="25"
                     PreviewMouseLeftButtonDown="SelectAll" />
    

    在codebehind中:

    private void SelectAll(object sender, MouseButtonEventArgs e)
    {
    
        TextBox tb = (sender as TextBox);
    
        if (tb == null)
        {
            return;
        }
    
        if (!tb.IsKeyboardFocusWithin)
        {
            tb.SelectAll();
            e.Handled = true;
            tb.Focus();
        }
    }
    
  • 5

    我有同样的问题 . 在VB.Net中,它的工作方式很简单:

    VB XAML:

    <TextBox x:Name="txtFilterFrequency" />
    

    Codehind:

    Private Sub txtFilterText_GotFocus(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles txtFilterText.GotFocus
        Me.Dispatcher.BeginInvoke(Sub()
                                      txtFilterText.SelectAll()
                                  End Sub, DispatcherPriority.ApplicationIdle, Nothing)
    End Sub
    

    C# (感谢ViRuSTriNiTy)

    private delegate void TextBoxSelectAllDelegate(object sender);
    
    private void TextBoxSelectAll(object sender)
    {
        (sender as System.Windows.Controls.TextBox).SelectAll();
    }
    
    private void MyTextBox_GotFocus(object sender, System.Windows.RoutedEventArgs e)
    {
        TextBoxSelectAllDelegate d = TextBoxSelectAll;
    
        this.Dispatcher.BeginInvoke(d,
            System.Windows.Threading.DispatcherPriority.ApplicationIdle, sender);
    }
    
  • 1

    我意识到这是非常古老的,但这是我的解决方案,它基于表达式/微软交互性和交互名称空间 .

    首先,我按照指令at this link将交互触发器放入样式中 .

    然后归结为此

    <Style x:Key="baseTextBox" TargetType="TextBox">
            <Setter Property="gint:InteractivityItems.Template">
                <Setter.Value>
                    <gint:InteractivityTemplate>
                        <gint:InteractivityItems>
                            <gint:InteractivityItems.Triggers>
                                <i:EventTrigger EventName="GotKeyboardFocus">
                                    <ei:CallMethodAction MethodName="SelectAll"/>
                                </i:EventTrigger>
                                <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
                                    <ei:CallMethodAction MethodName="TextBox_PreviewMouseLeftButtonDown"
                                        TargetObject="{Binding ElementName=HostElementName}"/>
                                </i:EventTrigger>
                            </gint:InteractivityItems.Triggers>
                        </gint:InteractivityItems>
                    </gint:InteractivityTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    

    还有这个

    public void TextBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            TextBox tb = e.Source as TextBox;
            if((tb != null) && (tb.IsKeyboardFocusWithin == false))
            {
                tb.Focus();
                e.Handled = true;
            }
        }
    

    就我而言,我有一个用户控件,其中文本框有代码隐藏 . 代码隐藏具有处理函数 . 我在xaml中给了我的用户控件一个名字,我正在使用该名称作为元素 . 这对我来说非常合适 . 只需将样式应用于您希望在文本框中单击时选择所有文本的任何文本框 .

    当文本框上的GotKeyboardFocus事件触发时,第一个CallMethodAction调用文本框的SelectAll函数 .

    我希望这有帮助 .

  • 68

    对于那些对Donnelle / Groky的方法感兴趣的人,但想要点击最后一个字符的右边(但仍然在TextBox中)将插入符号放在输入文本的末尾,我想出了这个解决方案:

    int GetRoundedCharacterIndexFromPoint(TextBox textBox, Point clickedPoint)
        {
            int position = textBox.GetCharacterIndexFromPoint(clickedPoint, true);
    
            // Check if the clicked point is actually closer to the next character
            // or if it exceeds the righmost character in the textbox
            // (in this case return increase the position by 1)
            Rect charLeftEdge = textBox.GetRectFromCharacterIndex(position, false);
            Rect charRightEdge = textBox.GetRectFromCharacterIndex(position, true);
            double charWidth = charRightEdge.X - charLeftEdge.X;
            if (clickedPoint.X + charWidth / 2 > charLeftEdge.X + charWidth) position++;
    
            return position;
        }
    
        void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
        {
            // Find the TextBox
            DependencyObject parent = e.OriginalSource as UIElement;
            while (parent != null && !(parent is TextBox))
                parent = VisualTreeHelper.GetParent(parent);
    
            if (parent != null)
            {
                var textBox = (TextBox)parent;
                if (!textBox.IsKeyboardFocusWithin)
                {
                    // If the text box is not yet focused, give it the focus and
                    // stop further processing of this click event.
                    textBox.Focus();
                    e.Handled = true;
                }
                else
                {
                    int pos = GetRoundedCharacterIndexFromPoint(textBox, e.GetPosition(textBox));
                    textBox.CaretIndex = pos;
                }
            }
        }
    
        void SelectAllText(object sender, RoutedEventArgs e)
        {
            var textBox = e.OriginalSource as TextBox;
            if (textBox != null)
                textBox.SelectAll();
        }
    

    GetRoundedCharacterIndexFromPoint方法取自this post .

  • -1
    #region TextBoxIDCard selection
        private bool textBoxIDCardGotFocus = false;
        private void TextBoxIDCard_GotFocus(object sender, RoutedEventArgs e)
        {
            this.TextBoxIDCard.SelectAll();
        }
    
        private void TextBoxIDCard_LostFocus(object sender, RoutedEventArgs e)
        {
            textBoxIDCardGotFocus = false;
        }
    
        private void TextBoxIDCard_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (textBoxIDCardGotFocus == false)
            {
                e.Handled = true;
                this.TextBoxIDCard.Focus();
                textBoxIDCardGotFocus = true;
            }
        } 
        #endregion
    
  • 1

    尝试使用此扩展方法将所需行为添加到任何TextBox控件 . 我还没有广泛测试它,但似乎满足了我的需求 .

    public static class TextBoxExtensions
    {
        public static void SetupSelectAllOnGotFocus(this TextBox source)
        {
            source.GotFocus += SelectAll;
            source.PreviewMouseLeftButtonDown += SelectivelyIgnoreMouseButton;
        }
    
        private static void SelectAll(object sender, RoutedEventArgs e)
        {
            var textBox = e.OriginalSource as TextBox;
            if (textBox != null)
                textBox.SelectAll();
        }
    
        private static void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
        {
            var textBox = (sender as TextBox);
            if (textBox != null)
            {
                if (!textBox.IsKeyboardFocusWithin)
                {
                    e.Handled = true;
                    textBox.Focus();
                }
            }
        }
    }
    
  • -1

    我搜索了很多解决方案,我找到了几个解决方案来选择但是,问题是当我们右键单击并在从文本框中选择部分文本后进行剪切/复制时,它会选择所有甚至我选择的部分文本 . 解决这个问题是解决方案 . 只需在键盘选择事件中添加以下代码即可 . 这对我有用 .

    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

    我使用了Nils的答案,但转换为更灵活 .

    public enum SelectAllMode
    {
    
        /// <summary>
        ///  On first focus, it selects all then leave off textbox and doesn't check again
        /// </summary>
        OnFirstFocusThenLeaveOff = 0,
    
        /// <summary>
        ///  On first focus, it selects all then never selects
        /// </summary>
        OnFirstFocusThenNever = 1,
    
        /// <summary>
        /// Selects all on every focus
        /// </summary>
        OnEveryFocus = 2,
    
        /// <summary>
        /// Never selects text (WPF's default attitude)
        /// </summary>
        Never = 4,
    }
    
    public partial class TextBox : DependencyObject
    {
        public static readonly DependencyProperty SelectAllModeProperty = DependencyProperty.RegisterAttached(
            "SelectAllMode",
            typeof(SelectAllMode?),
            typeof(TextBox),
            new PropertyMetadata(SelectAllModePropertyChanged));
    
        private static void SelectAllModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is System.Windows.Controls.TextBox)
            {
                var textBox = d as System.Windows.Controls.TextBox;
    
                if (e.NewValue != null)
                {
                    textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;
                    textBox.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
                }
                else
                {
                    textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;
                    textBox.PreviewMouseLeftButtonDown -= OnMouseLeftButtonDown;
                }
            }
        }
    
        private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DependencyObject dependencyObject = GetParentFromVisualTree(e.OriginalSource);
    
            if (dependencyObject == null)
                return;
    
            var textBox = (System.Windows.Controls.TextBox)dependencyObject;
            if (!textBox.IsKeyboardFocusWithin)
            {
                textBox.Focus();
                e.Handled = true;
            }
        }
    
        private static DependencyObject GetParentFromVisualTree(object source)
        {
            DependencyObject parent = source as UIElement;
            while (parent != null && !(parent is System.Windows.Controls.TextBox))
            {
                parent = VisualTreeHelper.GetParent(parent);
            }
    
            return parent;
        }
    
        private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
        {
            var textBox = e.OriginalSource as System.Windows.Controls.TextBox;
            if (textBox == null) return;
    
            var selectAllMode = GetSelectAllMode(textBox);
    
            if (selectAllMode == SelectAllMode.Never)
            {
                textBox.SelectionStart = 0;
                textBox.SelectionLength = 0;
            }
            else
                textBox.SelectAll();
    
            if (selectAllMode == SelectAllMode.OnFirstFocusThenNever)
                SetSelectAllMode(textBox, SelectAllMode.Never);
            else if (selectAllMode == SelectAllMode.OnFirstFocusThenLeaveOff)
                SetSelectAllMode(textBox, null);
        }
    
        [AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
        [AttachedPropertyBrowsableForType(typeof(System.Windows.Controls.TextBox))]
        public static SelectAllMode? GetSelectAllMode(DependencyObject @object)
        {
            return (SelectAllMode)@object.GetValue(SelectAllModeProperty);
        }
    
        public static void SetSelectAllMode(DependencyObject @object, SelectAllMode? value)
        {
            @object.SetValue(SelectAllModeProperty, value);
        }
    }
    

    在XAML中,您可以使用以下其中一种:

    <!-- On first focus, it selects all then leave off textbox and doesn't check again -->
    <TextBox attprop:TextBox.SelectAllMode="OnFirstFocusThenLeaveOff" />
    
    <!-- On first focus, it selects all then never selects -->
    <TextBox attprop:TextBox.SelectAllMode="OnFirstFocusThenNever" />
    
    <!-- Selects all on every focus -->
    <TextBox attprop:TextBox.SelectAllMode="OnEveryFocus" />
    
    <!-- Never selects text (WPF's default attitude) -->
    <TextBox attprop:TextBox.SelectAllMode="Never" />
    
  • 2

    在doubleclick之后覆盖mouseDown并选择all的简单方法是:

    public class DoubleClickTextBox: TextBox
    {
    
        public override void EndInit()
        {
            base.EndInit();            
        }
    
        protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e)
        {
            base.OnMouseEnter(e);
            this.Cursor = Cursors.Arrow;
        }
        protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
        {
    
        }
    
        protected override void OnMouseDoubleClick(System.Windows.Input.MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);
            this.SelectAll();
        }
    }
    
  • 14

    谢尔盖 .

    在谷歌搜索和测试后,我找到了一个适合我的简单解决方案 .

    您需要将事件处理程序添加到容器窗口的“已加载”事件:

    private void yourwindow_Loaded(object sender, RoutedEventArgs e)
        {
            EventManager.RegisterClassHandler(typeof(TextBox),
                TextBox.PreviewMouseLeftButtonDownEvent,
                new RoutedEventHandler(SelectivelyIgnoreMouseButton));
        }
    

    接下来,您必须在以前的代码中为引用的RoutedEventHandler创建处理程序:

    private void SelectivelyIgnoreMouseButton(object sender, RoutedEventArgs e)
        {
            TextBox tb = (sender as TextBox);
            if (tb != null)
            {
                if (!tb.IsKeyboardFocusWithin)
                {
                    e.Handled = true;
                    tb.Focus();
                }
            }
        }
    

    现在,您可以将GotFocus事件处理程序上的SelectAll()命令分别添加到任何TextBox控件:

    private void myTextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            (sender as TextBox).SelectAll();
        }
    

    现在您的文字在焦点上被选中!

    改编自Dr. WPF solution, MSDN Forums

  • 2

    这是@Nasenbaer发布的answer的C#版本

    private delegate void TextBoxSelectAllDelegate(object sender);
    
    private void TextBoxSelectAll(object sender)
    {
        (sender as System.Windows.Controls.TextBox).SelectAll();
    }
    
    private void MyTextBox_GotFocus(object sender, System.Windows.RoutedEventArgs e)
    {
        TextBoxSelectAllDelegate d = TextBoxSelectAll;
    
        this.Dispatcher.BeginInvoke(d,
            System.Windows.Threading.DispatcherPriority.ApplicationIdle, sender);
    }
    

    MyTextBox_GotFocus 是分配给 MyTextBoxGotFocus 事件的事件处理程序 .

  • 9

    我测试了所有这些,但只有以下结果:

    protected override void OnStartup(StartupEventArgs e) 
            {
                EventManager.RegisterClassHandler(typeof(TextBox), UIElement.PreviewMouseLeftButtonDownEvent,
               new MouseButtonEventHandler(SelectivelyHandleMouseButton), true);
                EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotKeyboardFocusEvent,
                  new RoutedEventHandler(SelectAllText), true);
                EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotFocusEvent,
                  new RoutedEventHandler(GotFocus), true);          
            }
    
            private static void SelectivelyHandleMouseButton(object sender, MouseButtonEventArgs e)
            {
                var textbox = (sender as TextBox);
                if (textbox != null)
                {
                    int hc = textbox.GetHashCode();
                    if (hc == LastHashCode)
                    {
                        if (e.OriginalSource.GetType().Name == "TextBoxView")
                        {
                            e.Handled = true;
                            textbox.Focus();
                            LastHashCode = -1;
                        }
                    }
                }
                if (textbox != null) textbox.Focus();
            }
    
            private static void SelectAllText(object sender, RoutedEventArgs e)
            {
                var textBox = e.OriginalSource as TextBox;
                if (textBox != null)
                    textBox.SelectAll();
            }
    
            private static int LastHashCode;
            private static void GotFocus(object sender, RoutedEventArgs e)
            {
                var textBox = e.OriginalSource as TextBox;
                if (textBox != null)
                    LastHashCode = textBox.GetHashCode();
            }
    
  • 40

    哇!阅读完上述所有内容后,我发现自己不堪重负 . 我接受了我在这篇文章中学到的东西并尝试了一些完全不同的东西 . 要在文本框中获得焦点时选择文本我使用:

    private void TextField_GotFocus(object sender, RoutedEventArgs e)
    {
        TextBox tb = (sender as Textbox);
        if(tb != null)
        {
            e.Handled = true;
            tb.Focus();
            tb.SelectAll();
        }
    }
    

    将文本框的GotFocus属性设置为此方法 .

    运行应用程序并在文本框中单击一次会突出显示文本框中的所有内容 .

    如果确实如此,目标是在用户点击文本框时选择文本,这看起来很简单并且涉及的代码少得多 . 只是说......

相关问题