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

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

It is more complex, while the accepted answer does the same thing in a simpler way. The usability of accepted answer is better. When you click in the middle of the text, text gets unselected when you release the mouse allowing you to start editing instantly, and if you still want to select all, just press the button again and this time it will not unselect on release. Following Donelle's recipe, if I click in the middle of text, I have to click second time to be able to edit. If I click somewhere within the text versus outside of the text, this most probably means I want to start editing instead of overwriting everything.


当前回答

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

Dim WithEvents Timer作为新的DispatcherTimer()

设置间隔: 计时器。Interval = timspan . frommilliseconds (20)

响应事件(我在这里继承了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

这就是全部!

其他回答

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

我以为这样简单多了。

nameOfTextbox.Focus();
nameOfTextbox.Select(0, nameOfTextbox.Text.Length);

同样,如果别人有你的光标不聚焦在文本框的问题,你可以使用这个在nameOfTextbox.Focus();以上。

Dispatcher.BeginInvoke(DispatcherPriority.Input,
new Action(delegate () {
    nameOfTextbox.Focus();         // Set Logical Focus
    Keyboard.Focus(nameOfTextbox); // Set Keyboard Focus
}));

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

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

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

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

将文本框的GotFocus属性设置为该方法。

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

如果目标确实是在用户单击文本框时选择文本,这看起来很简单,涉及的代码也少了很多。只是说……

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

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

——编辑——

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

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