如果我从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.


当前回答

对于那些对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方法取自这篇文章。

其他回答

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

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

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

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

我以为这样简单多了。

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

最简单和完美的解决方案,是在文本框获得焦点后使用计时器选择所有文本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

这就是全部!

我也有同样的问题。在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);
}