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


232

如果我SelectAllGotFocus事件处理程序中调用,它将无法使用鼠标-释放鼠标后所选内容就会消失。

编辑:人们喜欢唐娜(Donnelle)的答案,我将尽力解释为什么我不喜欢被接受的答案。

  • 它更复杂,而被接受的答案则以更简单的方式完成相同的事情。
  • 接受答案的可用性更好。当您单击文本的中间部分时,释放鼠标时文本将不会被选中,从而使您可以立即开始编辑;如果仍然要选择全部,只需再次按下该按钮,这次就不会在选择时取消选择。按照Donelle的食谱,如果我单击文本中间的内容,则必须第二次单击才能进行编辑。如果单击文本中的某个地方而不是文本外部的某个地方,这很可能意味着我要开始编辑而不是覆盖所有内容。

如果您要使用多个表格,那么她的答案将继续比第一个表格复杂。这两个选项的可用性都是没有意义的,因为您可以更改两个选项的工作方式。
thepaulpage 2011年

1
@Sergey:您可能想更改此问题的可接受答案,因为此后有了更好的答案。我不会建议我,但您可以;)
Grokys

问题具有Silverlight标签,但Silverlight根本没有大多数事件/根本没有任何预览事件。那么应该使用哪种解决方案?
Valentin Kuzub,2011年

链接“为什么对WPF的关注如此棘手?” 坏了
麦克森

1
如以下有关stackoverflow.com/a/2553297/492的评论中所述,madprops.org/blog/wpf-textbox-selectall-on-focus是一个简单的解决方案,并保留了原始的nono行为。我将事件注册放入构造函数中,因为应用程序中只有一个WPF控件。
CAD bloke 2015年

Answers:


75

不知道为什么它会在GotFocus事件中丢失选择。

但是一种解决方案是对GotKeyboardFocusGotMouseCapture事件进行选择。这样,它将始终有效。


10
不。在现有文本中间用鼠标单击时-释放鼠标按钮时,选择将丢失。
谢尔盖·阿尔杜霍夫

3
虽然-在第二次单击后,它将再次选择所有文本...不确定这是否是WPF设计人员的预期行为,但是可用性还不错。与单个GotFocus处理程序的另一个不同之处在于,单击TextBox中的空白区域会选择全部。
谢尔盖·阿尔杜霍夫

3
这也是我的拳头解决方案。但是我发现,当用户无法使用鼠标选择文本时,他们真的很烦,因为每次单击时都会选中整个文本……
Nils 2010年

1
该解决方案的另一个缺点是,当您使用TextBox的“剪切/复制/粘贴”菜单时,在选择任何菜单项时都会选择整个文本。

@gcores我知道这很旧了,但是没有人知道为什么在GotFocus事件中所选的文本丢失了吗?您认为它在其他事件中的工作是正确的,但这在我的书中是完全可以接受的解决方案。
2015年

210

我们拥有它,因此第一单击将全选,然后单击光标(我们的应用程序设计用于带笔的数位板)。

您可能会发现它很有用。

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

9
非常感谢你。这效果很好,应该是恕我直言的答案。当TextBox通过键盘或鼠标(显然是手写笔)获得焦点时,以上代码将起作用。+1
Drew Noakes

5
我在这里看到了几乎相同的答案social.msdn.microsoft.com/Forums/en-US/wpf/thread/…,它也很好用,但是它既不使用e.OriginalSource,也不在视觉树中爬行。这一切有好处吗?
Marco Luglio 09年

1
效果很好,但是如果仍然允许使用鼠标拖动选择文本,那将是完美的。Google Chrome地址栏是理想系统的完美示例:如果用户单击并释放时没有拖动,则会突出显示整个文本。但是,如果用户单击并拖动,则拖动通常会选择文本而不选择全部。SelectAll仅在释放鼠标时发生。我会摆弄,看看我是否可以完全改进此设计。
devios1 2010年

2
该解决方案的另一个缺点是,当您使用TextBox的“剪切/复制/粘贴”菜单时,在选择任何菜单项时都会选择整个文本。

1
我发现在SelectAllText方法上进行textBox.IsFocused了另一项测试可以改善它。GetKeyboardFocus由于alt键进入程序时,您不想全部选择。
Scott Stafford 2014年

164

Donnelle的答案效果最好,但是不得不派一个新的班级来使用它很痛苦。

我没有这样做,而是在App.xaml.cs中为应用程序中的所有TextBox注册了处理程序。这使我可以将Donnelle的答案与标准TextBox控件一起使用。

将以下方法添加到您的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
这是一个非常酷的解决方案,Matt Hamilton早在这里也曾描述过:madprops.org/blog/wpf-textbox-selectall-on-focus
Ashley Davis,2010年

在“接收”,“重点突出”中有一些拼写错误
Nate Zaugg

2
谢谢Nate,他的纠正是正确的,尽管在我的辩护中,我还是想指出从Donnelle的回答中逐字复制了拼写错误;)
Grokys 2011年

问题具有Silverlight标签,但Silverlight根本没有大多数事件/根本没有任何预览事件。那么应该使用哪种解决方案?在此先感谢
Valentin Kuzub 2011年

4
“重点拼写在美国更为常见;但是,重点拼写有时在英国和加拿大使用,在澳大利亚和新西兰尤为常见。” 等等;)
Donnelle

85

这已经很老了,但我还是会显示答案。

我选择了Donnelle的答案的一部分(跳过双击),因为我认为这更自然。但是,像gcores一样,我不喜欢创建派生类的需求。但是我也不喜欢gcores OnStartup方法。我需要“通常但并非总是如此”。

我已将此作为附件实现,DependencyProperty因此可以local:SelectTextOnFocus.Active = "True"在xaml中进行设置。我觉得这种方式最令人愉快。

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

对于我的“常规但并非总是如此”功能,我将此Attache属性设置为True在(全局)中TextBox Style。这样,“选择文本”始终处于“打开”状态,但是我可以基于每个文本框禁用它。


8
+1比全局设置好得多,并且比从TextBox派生的更“ WPF方式”。
stijn 2012年

3
+1同意stijn。对于那些不得不弄清为什么SelectAllOnFocus发生的可怜的开发人员,在app.cs中“隐藏”您的代码并不好。:-)我刚刚将其放入TextBoxBehaviors的类中,然后更新了我的基本TextBox样式。工作了请客。干杯
李·坎贝尔

2
@tronda:只需使用TextBox的TargetType向资源添加样式。我建议您看看wpftutorial.net/Styles.html
Nils

2
最佳答案的另外+1。我发现的唯一问题是,即使我使用鼠标右键也经常选择文本(我经常通过上下文菜单来编辑文本),该解决方案在这种情况下不起作用,因为即使我我总是选择所有文本只是想通过上下文菜单剪切1个字。你们知道如何解决这个问题吗?
user3313608

2
我喜欢这个答案,但是为什么要扩展DependencyObject?我删除了它,但仍然可以正常工作。
弗雷德

47

为方便起见,以下是实现答案解决方案的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的容器的根目录:

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

到目前为止,这是最好,最干净的解决方案。非常感谢您的分享。
Golvellius

它看起来确实不错,但是由于某种原因它破坏了选项卡控制...知道为什么吗?
2013年

我想使用您的解决方案。但是真的迷路了……也许您有样品吗?
Juan Pablo Gomez 2014年

当您在聚焦时单击文本框中的某个位置(想象您要将插入号移动到另一个位置)时,它将再次全选,而不是移动插入号。真是出乎意料 通过使用常见的MouseDoubleClick替换GotMouseCapture来修复此问题。感谢MSDN的最新解决方案。
norekhov 2014年

1
当文本框通过FocusManager.FocusedElement获得初始焦点时,它似乎不起作用。有什么想法吗?
szx 2015年

24

尽管这是一个古老的问题,但我刚刚遇到了这个问题,但是使用了“附加行为”解决了这个问题,而不是像谢尔盖的回答中那样使用“表达行为”解决了。这意味着我不需要System.Windows.InteractivityBlend SDK中的依赖项:

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.IsReadOnly && textBox.IsKeyboardFocusWithin)) return;

        e.Handled = true;
        textBox.Focus();
    }
}

然后,您可以像下面这样在XAML中使用它:

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

我在这里写了博客。


我喜欢这种方法,但Get / Set方法不应以“ Property”结尾。添加Xaml部分后,我必须删除该代码才能进行代码编译。
Patrick Quirk

非常好,按预期工作。我之所以喜欢它,是因为它有助于我在进行MVVM时将视图关注点分离。
Killnine 2014年

16

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

1
本质上,这与该线程中评分最高的解决方案相同。但是自两年前以来,现在我知道从@Donnelle那里借来的东西;)
谢尔盖·阿尔杜霍夫

这个解决方案似乎是最简单的,并且对我有用。我希望在进入文本框时默认选择特定的文本子集。
Jack B Nimble

10

我认为这很好用:

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

我猜这是最简单的实现方法。创建扩展方法后,您只需要调用myTextBox.SelectAllText()即可。为什么这个答案没有得到更多积分?为什么其他解决方案这么好?
Tono Nam

2
我会避免使用此方法,因为它依赖于异步调用以在文本框的MouseUp处理程序之后运行。我不相信这是100%确定性的,并且可能导致行为不一致。即使它不太可能发生,我还是希望使用上述的surefire方法。
罗伯H

6

这是尝试解决其他解决方案中的一些问题的尝试:

  1. 使用右键单击上下文菜单进行剪切/复制/粘贴会选择所有文本,即使您没有全部选择。
  2. 从右键单击上下文菜单返回时,始终选中所有文本。
  3. 使用Alt+ 返回到应用程序时Tab,将始终选择所有文本。
  4. 尝试在首次点击时仅选择部分文本时,始终会选择全部(例如,不同于Google chromes地址栏)。

我编写的代码是可配置的。您可以在什么样的行动的选择所有的行为选择应设置三个只读字段发生:SelectOnKeybourdFocusSelectOnMouseLeftClickSelectOnMouseRightClick

该解决方案的缺点是它更加复杂并且存储了静态状态。与TextBox控件的默认行为似乎是一场丑陋的斗争。尽管如此,它仍然有效,并且所有代码都隐藏在Attached Property容器类中。

public static class TextBoxExtensions
{
    // Configuration fields to choose on what actions the select all behavior should occur.
    static readonly bool SelectOnKeybourdFocus = true;
    static readonly bool SelectOnMouseLeftClick = true;
    static readonly bool SelectOnMouseRightClick = true;

    // Remembers a right click context menu that is opened 
    static ContextMenu ContextMenu = null;

    // Remembers if the first action on the TextBox is mouse down 
    static bool FirstActionIsMouseDown = false;

    public static readonly DependencyProperty SelectOnFocusProperty =
        DependencyProperty.RegisterAttached("SelectOnFocus", typeof(bool), typeof(TextBoxExtensions), new PropertyMetadata(false, new PropertyChangedCallback(OnSelectOnFocusChanged)));

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(TextBox))]
    public static bool GetSelectOnFocus(DependencyObject obj)
    {
        return (bool)obj.GetValue(SelectOnFocusProperty);
    }

    public static void SetSelectOnFocus(DependencyObject obj, bool value)
    {
        obj.SetValue(SelectOnFocusProperty, value);
    }

    private static void OnSelectOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (!(d is TextBox textBox)) return;

        if (GetSelectOnFocus(textBox))
        {
            // Register events
            textBox.PreviewMouseDown += TextBox_PreviewMouseDown;
            textBox.PreviewMouseUp += TextBox_PreviewMouseUp;
            textBox.GotKeyboardFocus += TextBox_GotKeyboardFocus;
            textBox.LostKeyboardFocus += TextBox_LostKeyboardFocus;
        }
        else
        {
            // Unregister events
            textBox.PreviewMouseDown -= TextBox_PreviewMouseDown;
            textBox.PreviewMouseUp -= TextBox_PreviewMouseUp;
            textBox.GotKeyboardFocus -= TextBox_GotKeyboardFocus;
            textBox.LostKeyboardFocus -= TextBox_LostKeyboardFocus;
        }
    }

    private static void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // If mouse clicked and focus was not in text box, remember this is the first click.
        // This will enable to prevent select all when the text box gets the keyboard focus 
        // right after the mouse down event.
        if (!textBox.IsKeyboardFocusWithin)
        {
            FirstActionIsMouseDown = true;
        }
    }

    private static void TextBox_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Select all only if:
        // 1) SelectOnMouseLeftClick/SelectOnMouseRightClick is true and left/right button was clicked
        // 3) This is the first click
        // 4) No text is selected
        if (((SelectOnMouseLeftClick && e.ChangedButton == MouseButton.Left) || 
            (SelectOnMouseRightClick && e.ChangedButton == MouseButton.Right)) &&
            FirstActionIsMouseDown &&
            string.IsNullOrEmpty(textBox.SelectedText))
        {
            textBox.SelectAll();
        }

        // It is not the first click 
        FirstActionIsMouseDown = false;
    }

    private static void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Select all only if:
        // 1) SelectOnKeybourdFocus is true
        // 2) Focus was not previously out of the application (e.OldFocus != null)
        // 3) The mouse was pressed down for the first after on the text box
        // 4) Focus was not previously in the context menu
        if (SelectOnKeybourdFocus &&
            e.OldFocus != null &&
            !FirstActionIsMouseDown &&
            !IsObjectInObjectTree(e.OldFocus as DependencyObject, ContextMenu))
        {
            textBox.SelectAll();
        }

        // Forget ContextMenu
        ContextMenu = null;
    }

    private static void TextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Remember ContextMenu (if opened)
        ContextMenu = e.NewFocus as ContextMenu;

        // Forget selection when focus is lost if:
        // 1) Focus is still in the application
        // 2) The context menu was not opened
        if (e.NewFocus != null
            && ContextMenu == null)
        {
            textBox.SelectionLength = 0;
        }
    }

    // Helper function to look if a DependencyObject is contained in the visual tree of another object
    private static bool IsObjectInObjectTree(DependencyObject searchInObject, DependencyObject compireToObject)
    {
        while (searchInObject != null && searchInObject != compireToObject)
        {
            searchInObject = VisualTreeHelper.GetParent(searchInObject);
        }

        return searchInObject != null;
    }
}

要将附加属性附加到TextBox,您需要做的就是添加xmlns附加属性的xml名称空间(),然后像这样使用它:

<TextBox attachedprop:TextBoxExtensions.SelectOnFocus="True"/>

有关此解决方案的一些注意事项:

  1. 要覆盖鼠标按下事件的默认行为并启用第一次单击时仅选择部分文本的功能,请在鼠标按下事件时选择所有文本。
  2. 我不得不面对这样一个事实,那就是TextBox它在失去焦点之后会记住它的选择。我实际上已经覆盖了这种行为。
  3. 我必须记住,按下鼠标是否是TextBoxFirstActionIsMouseDown静态字段)。
  4. 我必须记住右键单击打开的上下文菜单(ContextMenu静态字段)。

我发现的唯一副作用是when SelectOnMouseRightClick是true。有时,右键单击上下文菜单在打开时闪烁,而在空白处单击鼠标右键TextBox则不会“全选”。


5

我发现这里提出的答案都没有模仿标准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;
    }
}

这是基于我在这里找到的代码。


1
虽然这是一个很好的答案,但我认为当用户单击空白时,他的意图(在业务应用程序中)最有可能覆盖整个价值,因此选择全部是正确的方法。
谢尔盖·阿尔杜霍夫

1
Sergey:第一次单击将选择整个值,第二次单击会将光标置于该值的右侧。在其他提出的解决方案中,第二次单击将保留整个选定的值,因此很难附加到该值。
克里斯多夫·韦比斯特

如何使用?我将此代码添加到App.xaml.cs中,但似乎对我的应用程序中的TextBoxes没有影响。
PIntag 2011年

5

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

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

4

在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应用程序中的所有内容。


3

这里拍摄:

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

3

我意识到这已经很老了,但这是我的解决方案,它基于表达式/ Microsoft交互性和交互性命名空间。

首先,我按照此链接上的说明将交互触发器放入样式中。

然后归结为

<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中为用户控件提供了一个名称,并且正在使用该名称作为元素。这对我来说是完美的。只需将样式应用于TextBox您想要在单击时选择所有文本的任何位置TextBox

当事件触发时,第一个CallMethodAction调用文本框的SelectAll方法。GotKeyboardFocusTextBox

我希望这有帮助。


由于这是一个很老的问题,因此如果您提到为什么有人选择这种方法,可能会帮助您的答案引起注意。
divibisan

首先,不需要将其放置在样式中,但是我认为很明显,有很多文本框控件都需要使用此样式,这是要走的路。
wiyosaya

1
也许有些人不同意这种方法,但是,关于为什么要使用这种方法,它不需要子类化TextBox,注册类处理程序事件,扩展方法,创建附加属性等。作为样式,也可以添加它到任何xaml项目的资源字典。如果没有x:Key,它将应用于资源字典范围内的任何TextBox实例,而无需更改每个单独文本框的xaml。在某些情况下,这可能是一种更清洁的方法。
wiyosaya

2

我使用了尼尔斯的答案,但转换为更灵活。

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" />

1
在模板中使用的一种非常好的解决方案,因为您可以将其绑定到xaml,而无需任何实际代码,只是扩展了文本框的行为。
埃里克·约翰逊

2

这是@Nasenbaer发布的答案的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分配给的GotFocus事件的事件处理程序MyTextBox


2

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

在XAML中,您可以TextBox说:

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

在代码背后:

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

1
可能想添加一个GotKeyboardFocus事件,其中包含TextBox.SelectAll(),供那些在您的应用程序中切换方式的人们使用。您的解决方案也适用于PasswordBoxes(因为PasswordBoxes是密封类型,因此无法扩展)。
David Sherret 2012年

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

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

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

1

我有同样的问题。在VB.Net中,这种方式很容易实现:

VB XAML:

<TextBox x:Name="txtFilterFrequency" />

代码隐藏:

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

对我来说最好的解决方案,我在这里发布了C#翻译:stackoverflow.com/a/48385409/3936440
ViRuSTriNiTy

对我来说,这种方法有时无法选择文本。我认为这是由于BeginInvoke导致的比赛条件。
Vimes

请明确说明。调度程序优先级正在按预期在默认应用程序上工作。你的情况如何?您是否按照描述进行了尝试?您的解决方案有什么特别之处吗?
Nasenbaer

1

到目前为止,这是最简单的解决方案。

将全局处理程序添加到应用程序(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文本框SelectAll on Focus

希望能帮助到你。


1

对于那些对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方法是从这篇文章中获得的。


1
工作正常,但不会触发双击事件
Rodrigo Caballero 2014年

实际上,它确实输入了doubleclick事件,但OriginalSource属性的类型为TextBoxView。因此,SelectAllText方法应如下所示:private static void SelectAllText(object sender,RoutedEventArgs e){var textBox = e.OriginalSource as TextBox; 如果(textBox!= null){textBox.SelectAll(); System.Diagnostics.Debug.WriteLine(“ Selected ALL”); }否则,如果(发送方为TextBox){(发送方为TextBox).SelectAll(); }
Rodrigo Caballero 2014年

1

经过谷歌搜索和测试之后,我找到了一个对我有用的简单解决方案。

您需要向Loaded容器窗口的事件添加事件处理程序:

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

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

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

现在,您的文本已被选中为焦点!

改编自MSDN论坛的WPF博士解决方案


我刚刚使用过:私有异步void TBTime_GotFocus(object sender,RoutedEventArgs e){TextBox tb =(TextBox)e.OriginalSource; 等待Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,async()=> {tb.SelectAll();}); }
David Jones

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

如果一个窗口上有20个文本框,是否会为每个文本框创建3个方法?这种方法不好。看看这里:rachel53461.wordpress.com/2011/11/05/...
亚历Dicu

0

这对我来说似乎很好。基本上,这是对一些早期文章的回顾。我只是将其放入构造函数中的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();
}

不错,很容易,但是似乎存在时间问题-每隔一次尝试(单击鼠标),它会立即再次取消选择...?
T4NK3R

0

覆盖mouseDown并在双击后全选的简单方法是:

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

0

尝试将其放在文本框所包含的任何控件的构造函数中:

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

当您将其放在窗口构造函数中时,这种方法不起作用。
ViRuSTriNiTy

0

如果有一个事件在OnFocus鼠标向上移动期间取消了对文本的选择,我通常会延迟全选。

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (TextBox.Text != null)
    {
        _ = Task.Run(() =>
        {
            Dispatcher.Invoke(
                async () => {
                    await Task.Delay(100);
                    TextBox.SelectAll();
                }
            );
        });
    }
}

-1

我已经测试了所有这些,但仅解决了以下问题:

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

4
这也是对哈希码的淫秽滥用。我会读的,链接
RichK 2011年

3
并且使用GetType().Name代替isashacky
RichK 2011年

-1

我看到有很多答案,但是作为已获批准的答案,应该使用的方法是 EditTextBoxGotCapture

后面有以下代码:

private void EditTextBoxGotCapture(object sender, MouseEventArgs e)
{
    if (sender is TextBox tb)
    {
        tb.Select(0, tb.Text.Length);
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.