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

时间:2012-08-02 22:48:48

标签: c# wpf xaml textbox focus

因此,假设我有一个带有多个文本框的WPF表单,如果您选中文本框并且其中已有内容,我想选择该框中的所有文本,因此键入将删除该文本。如果您在框中单击鼠标,则可能意味着您想要在某处更改字母,因此在这种情况下不要突出显示所有字母。看起来很容易,但到目前为止,我找不到一个好的解决方案。这是我到目前为止非常关闭工作,但不是很完美。

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

因此,当该框获得键盘焦点时,它会选择全部,因此对文本框进行选项卡可以完美地选择所有文本。但是,如果鼠标单击此方法也会被调用,这也会突出显示文本,但是单击然后将光标放在鼠标单击之后。所以在功能上它是完美的,但它仍然困扰我,当鼠标点击时它闪烁选择一切。有没有更好的方法,或者在我的活动中进行某种检查,以便知道我通过鼠标点击而不是标签获得了键盘焦点?

5 个答案:

答案 0 :(得分:21)

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

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

但实际上有一种更好的方法,因为焦点在按键上移动,你可以检查键盘。我建议使用GotKeyboardFocus处理程序的正确签名来获取相应的event-args:

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

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

答案 1 :(得分:1)

您可以尝试在焦点事件发生时检查TextBox中是否存在鼠标并检查鼠标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();
}

和H.B.指出你可以尝试使用txt.IsMouseOver属性来确定Cursor是否在TextBox的Client Rectangle中。它看起来更干净。

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

答案 2 :(得分:0)

可以捕获最后一个按下的键并在你的事件中与之进行比较

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

并在您的活动中:

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

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

这并不完美,因为他们可以点击标签(而不是标签进入你的控件),而不是点击你的控件。但它大部分时间都会起作用。

答案 3 :(得分:0)

您可以使用附加行为模式

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

只需要你的xaml

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

使用你可以在TextBox中使用

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

鼠标和键盘事件的所有这些工作

答案 4 :(得分:0)

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

var chmod = require('chmod');
chmod("outputFile", 500);