wpf 选项卡上的文本框全选但不是鼠标单击

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11786931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 04:49:16  来源:igfitidea点击:

Textbox SelectAll on tab but not mouse click

c#wpfxamltextboxfocus

提问by Kevin DiTraglia

So lets say I have a WPF form with several text boxes, if you tab to the text box and it already has something in it, I want to select all the text in that box so typing will erase that text. If you mouse click on the box, it probably means you want to change a letter somewhere, so do not highlight all in this case. Seems easy enough, but a good solution as so far eluded me. Here's what I have so far that is very closeto working, but not quite perfect.

因此,假设我有一个带有多个文本框的 WPF 表单,如果您使用 Tab 键切换到文本框并且其中已经包含一些内容,我想选择该框中的所有文本,以便键入会删除该文本。如果您用鼠标单击该框,则可能意味着您想在某处更改字母,因此在这种情况下不要突出显示所有字母。似乎很容易,但到目前为止我还没有找到一个好的解决方案。到目前为止,这是我非常接近工作但并不完美的内容。

<Style x:Key="TextBoxStyle" TargetType="TextBox">
    <EventSetter Event="GotKeyboardFocus" Handler="EventSetter_OnHandler" />
</Style>

private void EventSetter_OnHandler(object sender, RoutedEventArgs e)
{
    TextBox txt = sender as TextBox;
    if (txt != null) txt.SelectAll();
}

So when the box gets keyboard focus it selects all, so tabbing to the text box selects all the text perfectly. However if the mouse clicks this method gets called as well, which also highlights the text, but the click then puts the cursor where the mouse clicked after. So functionally it's perfect, but it still bothers me that it flickers selecting everything when the mouse clicks. Any better way to do this, or put some kind of check in my event to know that I gained keyboard focus from a mouse click and not a tab?

因此,当该框获得键盘焦点时,它会选择全部,因此使用 Tab 键切换到文本框可以完美地选择所有文本。但是,如果鼠标单击此方法也会被调用,这也会突出显示文本,但是单击会将光标放在鼠标单击的位置。所以在功能上它是完美的,但它仍然困扰着我,当鼠标点击时它会闪烁选择所有内容。有没有更好的方法来做到这一点,或者在我的事件中进行某种检查,以了解我是通过单击鼠标而不是选项卡获得了键盘焦点?

回答by H.B.

Have not seen any clean solution so far sadly, one thing you could do is just check the mouse state:

遗憾的是,到目前为止还没有看到任何干净的解决方案,您可以做的一件事就是检查鼠标状态:

var tb = (TextBox)sender;
if (Mouse.LeftButton != MouseButtonState.Pressed)
    tb.SelectAll();

But there actually is a better way, as the focus shifts on key down you can check the keyboard instead. I would recommend using the proper signature for the GotKeyboardFocushandler to get the appropriate event-args:

但实际上有更好的方法,当焦点转移到按键上时,您可以检查键盘。我建议为GotKeyboardFocus处理程序使用正确的签名来获取适当的事件参数:

private void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    if (e.KeyboardDevice.IsKeyDown(Key.Tab))
        ((TextBox)sender).SelectAll();
}

At this point you may still see some selection getting cleared upon click but that is just because the previous selection only gets hidden if unfocused. You can always clear the selection in LostKeyboardFocusto prevent that (e.g. ((TextBox)sender).Select(0, 0)).

在这一点上,您可能仍然会看到一些选择在单击时被清除,但这只是因为前一个选择只有在未聚焦时才会被隐藏。您可以随时清除选择LostKeyboardFocus以防止出现这种情况(例如((TextBox)sender).Select(0, 0))。

回答by Mark Hall

You could try checking if the Mouse is present in the TextBox when the Focus Event happens and check the Mouse ButtonButtonState. This is not perfect but should be close to what you are looking for.

当焦点事件发生时,您可以尝试检查鼠标是否存在于文本框中,并检查鼠标 ButtonButtonState。这并不完美,但应该接近您正在寻找的内容。

private void EventSetter_OnHandler(object sender, RoutedEventArgs e)
{
    TextBox txt = sender as TextBox;
    Point position = Mouse.GetPosition(txt);
    // if Mouse position is not in the TextBox Client Rectangle
    // and Mouse Button not Pressed.
    if((!(new Rect(0,0,txt.Width,txt.Height)).Contains(position)) || ( Mouse.LeftButton != MouseButtonState.Pressed))
        if (txt != null) txt.SelectAll();
}

and as H.B. Pointed out you could try using the txt.IsMouseOver Property to determine if the Cursor is inside the TextBox's Client Rectangle. It looks a lot cleaner.

正如 HB 指出的那样,您可以尝试使用 txt.IsMouseOver 属性来确定光标是否在 TextBox 的客户端矩形内。它看起来干净了很多。

private void EventSetter_OnHandler(object sender, RoutedEventArgs e)
{
    TextBox txt = sender as TextBox;
    if( !txt.IsMouseOver || Mouse.LeftButton != MouseButtonState.Pressed)
        if (txt != null) txt.SelectAll();
}

回答by rkmax

You can use attached behavior pattern

您可以使用附加的行为模式

public class Behaviors
{
    public static readonly DependencyProperty SelectTextOnFocusProperty = DependencyProperty
        .RegisterAttached("SelectTextOnFocus", typeof(bool), typeof(Behaviors), new FrameworkPropertyMetadata(false, GotFocus));

    public static void SetSelectTextOnFocus(DependencyObject obj, bool value)
    {
        obj.SetValue(SelectTextOnFocusProperty, value);
    }

    private static void GotFocus(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var textbox = d as TextBox;

        if (null == textbox) return;

        textbox.GotKeyboardFocus += SelectTextOnFocus;
        textbox.GotMouseCapture += SelectTextOnFocus;
    }

    private static void SelectTextOnFocus(object sender, RoutedEventArgs e)
    {
        if (!(sender is TextBox)) return;
        ((TextBox)sender).SelectAll();
    }
}

in your xaml only need

在你的 xaml 中只需要

xmlns:my="clr-namespace:Namespace;assembly=Rkmax"

use you can use in a TextBox like

使用您可以在 TextBox 中使用,例如

<TextBox my:Behaviors.SelectTextOnFocus="True" />

all this work for mouse and keyboard event

所有这些都适用于鼠标和键盘事件

回答by Sambu Praveen

I searched a lot for the solution, I found couple of solutions to selectall But, the issue is when we do right click and do cut/copy after selecting part of text from text box, it selects all even I selected part of text. To fix this here is the solution. Just add the below code in the keyboard select event. This worked for me.

我搜索了很多解决方案,我找到了几个解决方案 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();
    }

回答by Nathan

You couldcapture the last key pressed and compare against it in your event

可以捕获最后按下的键并在您的事件中与它进行比较

private Key lastKey;
protected override void OnKeyDown(KeyEventArgs e)
{
     lastKey = e.Key;
     base.OnKeyDown(e);
}

and in your event:

在您的活动中:

private void EventSetter_OnHandler(object sender, RoutedEventArgs e)
{
    if(lastKey != Key.Tab)
        return;

    TextBox txt = sender as TextBox;
    if (txt != null) txt.SelectAll();
}

It's not perfect because they could have hit tab (not tabbing into your control) and than click into it your control. But it will work most of the time.

这并不完美,因为他们可以点击 Tab(不是 Tab 进入您的控件)然后点击它进入您的控件。但它会在大部分时间工作。