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

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

编辑:人们喜欢唐纳利的回答,我将试着解释为什么我不像公认的答案那样喜欢它。

  • 它更复杂,而公认的答案以更简单的方式做同样的事情。
  • 已接受答案的可用性较好。当您在文本中间单击时,当您释放鼠标时,文本将被取消选中,允许您立即开始编辑,如果您仍然想全选,只需再次按下按钮,这一次在释放时它将不会取消选择。按照Donelle的方法,如果我在文本中间点击,我必须点击第二次才能编辑。如果我点击文本内的某个地方而不是文本外,这很可能意味着我想开始编辑而不是覆盖所有内容。
171111 次浏览

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

但是一个解决方案是在GotKeyboardFocusGotMouseCapture事件上进行选择。这样它就能一直工作。

——编辑——

在这里添加一个例子来告诉人们如何解决上面提到的一些缺点:

private void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
// Fixes issue when clicking cut/copy/paste in context menu
if (textBox.SelectionLength == 0)
textBox.SelectAll();
}


private void TextBox_LostMouseCapture(object sender, MouseEventArgs e)
{
// If user highlights some text, don't override it
if (textBox.SelectionLength == 0)
textBox.SelectAll();


// further clicks will not select all
textBox.LostMouseCapture -= TextBox_LostMouseCapture;
}


private void TextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
// once we've left the TextBox, return the select all behavior
textBox.LostMouseCapture += TextBox_LostMouseCapture;
}

我们有它,所以第一次点击选择所有,另一次点击光标(我们的应用程序是设计用于平板电脑与笔)。

你可能会发现它很有用。

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

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

一个用于附加到单个文本框:

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

一个用于附加到包含多个文本框的容器的根:

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

Donnelle的答案是最好的,但是必须派生一个新的类来使用它是一种痛苦。

我没有这样做,而是在App.xaml.cs中为应用程序中的所有文本框注册处理程序。这允许我使用一个标准的文本框控件唐纳利的答案。

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

我选择了Donnelle的回答的一部分(跳过双击),因为我认为这更自然。然而,像grokies一样,我不喜欢创建派生类的需要。但我也不喜欢Grokys的OnStartup方法。我需要这个“一般但不总是”;的基础上。

我已经实现了一个附加的DependencyProperty,所以我可以在xaml中设置local:SelectTextOnFocus.Active = "True"。我觉得这种方式最令人愉快。

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

对于我的“一般但不总是”;我将这个附件属性设置为True在一个(全局)TextBox Style。这样“选择文本”;总是“开启”,但我可以在每个文本框的基础上禁用它。

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

我在这里给出的答案在这方面表现得更好。它是一个行为(因此它需要混合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;
}
}

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

我已经测试了所有的,但只有以下工作:

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

这对我来说似乎很有效。它基本上是一些早期帖子的重述。我只是把它放到构造函数的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();
}

我对此有一个稍微简化的答案(只有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();
}
}

对于那些对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方法取自 post。

#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

我认为这很有效:

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的问题没有直接关系,但我还是发布了它,因为它演示了使用DispatcherUIElement一起工作的相同模式。

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

尝试这个扩展方法,添加所需的行为到任何文本框控件。我还没有对它进行广泛测试,但它似乎满足了我的需求。

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

一个简单的方法来覆盖鼠标向下和选择所有双击后:

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

我也有同样的问题。在VB。Net的工作方式很简单:

<强> VB XAML: < / p >

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

下面是关于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();
}
}
}

我用附加行为解决了这个问题,而不是谢尔盖回答中的表达式行为。这意味着我不需要在Blend 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.IsReadOnly && textBox.IsKeyboardFocusWithin)) return;


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

然后你可以像这样在XAML中使用它:

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

我在博客上写过。

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

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

摘自在这里:

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

哇!读完以上所有内容后,我发现自己不知所措。我从这篇文章中学到了一些东西,并尝试了一些完全不同的东西。为了在TexTbox对象获得焦点时选择文本,我使用以下命令:

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

TexTboxGotFocus属性设置为该方法。

运行应用程序并在TexTbox中单击一次,将突出显示TexTbox中已经存在的所有内容。

如果目标确实是在用户单击TexTbox时选择文本,这似乎很简单,涉及的代码也少得多。只是说……

试着把这个放在你的文本框的任何控件的构造函数中:

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

在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

我搜索了很多解决方案,我发现了两个解决方案选择但是,问题是,当我们做右键单击,并从文本框选择部分文本后进行剪切/复制,它选择了所有甚至我选择了部分文本。解决办法就在这里。只需在键盘选择事件中添加以下代码。这对我很管用。

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

我使用了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" />

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

你需要在容器窗口的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();
}
}
}

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

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

您的文本现在被选中对焦!

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

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

向应用程序(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文本框选择焦点

希望能有所帮助。

下面是@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是分配给MyTextBoxGotFocus事件的事件处理程序。

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

首先,我遵循指令在此链接将交互触发器放入样式中。

然后就归结为这个

<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时,你想要选中所有文本。

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

我希望这能有所帮助。

如果在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. 使用右键上下文菜单剪切/复制/过去选择所有的文本,即使你没有选择它。
  2. 当从右击上下文菜单返回时,总是选择所有文本。
  3. 当使用Alt+选项卡返回应用程序时,总是选择所有文本。
  4. 当尝试只选择第一次点击的部分文本时,总是选择全部(不像谷歌chromes地址栏)。

我写的代码是可配置的。你可以通过设置三个只读字段:SelectOnKeybourdFocusSelectOnMouseLeftClickSelectOnMouseRightClick来选择select all行为应该发生的动作。

这种解决方案的缺点是它更复杂,并且存储的是静态状态。它似乎与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,所需要做的就是添加附加属性的xml命名空间(xmlns),然后像这样使用它:

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

关于这个解决方案的一些注意事项:

  1. 若要覆盖鼠标按下事件的默认行为,并启用在第一次单击时只选择部分文本,则在鼠标按下事件时选择所有文本。
  2. 我不得不处理这样一个事实:TextBox在失去焦点后还记得它的选择。实际上我已经重写了这个行为。
  3. 我必须记住,如果鼠标按下是TextBox (FirstActionIsMouseDown静态字段)上的第一个动作。
  4. 我必须记住右键单击打开的上下文菜单(ContextMenu静态字段)。

我发现唯一的副作用是当SelectOnMouseRightClick为真。有时右键单击上下文菜单会在其打开时闪烁,并且右键单击TextBox中的空白部分不会执行“全选”。

最简单和完美的解决方案,是在文本框获得焦点后使用计时器选择所有文本20ms:

Dim WithEvents Timer As New DispatcherTimer()

Timer.Interval = TimeSpan.FromMilliseconds(20) < / p >

响应事件(我在这里继承了TextBox控件,所以我重写了它的事件:

Protected Overrides Sub OnGotFocus(e As RoutedEventArgs)
Timer.Start()
MyBase.OnGotFocus(e)
End Sub




Private Sub Timer_Tick(sender As Object, e As EventArgs) Handles Timer.Tick
Timer.Stop()
Me.SelectAll()
End Sub

这就是全部!

我使用这个代码

  private void txtNav_GotFocus(object sender, RoutedEventArgs e)
{
e.Handled = true;
var c = new DispatcherTimer();
c.Interval = TimeSpan.FromMilliseconds(100);
c.Tick += (a1, a2) =>
{
c.IsEnabled = false;
txtNav.SelectAll();
};
c.IsEnabled = true;
    

}

对我来说,这是一个优秀的工作后,点击文本框上的鼠标:

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
Dispatcher.BeginInvoke(() => ((TextBox)sender).SelectAll());
e.Handled = true;
}

这似乎对我有用……

private bool TextBoxFocusBool;


private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
TextBoxFocusBool = true;
}


private void TextBox_LostMouseCapture(object sender, MouseEventArgs e)
{
if (TextBox.SelectionLength == 0 & TextBoxFocusBool == true)
{
TextBox.SelectAll();
TextBoxFocusBool = false;
}
}


private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
TextBoxFocusBool = true;
}