当前位置:  开发笔记 > 编程语言 > 正文

制作WinForms TextBox的行为与浏览器的地址栏相似

如何解决《制作WinFormsTextBox的行为与浏览器的地址栏相似》经验,为你挑选了4个好方法。

当C#WinForms文本框获得焦点时,我希望它的行为类似于浏览器的地址栏.

要查看我的意思,请单击您的Web浏览器的地址栏.您会注意到以下行为:

    如果文本框之前没有聚焦,则单击文本框应选择所有文本.

    鼠标按下并在文本框中拖动应该只选择我用鼠标突出显示的文本.

    如果文本框已经聚焦,则单击不会选择所有文本.

    以编程方式或通过键盘选项卡聚焦文本框应选择所有文本.

我想在WinForms中做到这一点.

最快的枪声:请在回答之前阅读以下内容!多谢你们.:-)

在.Enter或.GotFocus事件期间调用.SelectAll()将不起作用,因为如果用户单击文本框,则插入符号将被放置在他单击的位置,从而取消选择所有文本.

在.Click事件期间调用.SelectAll()将不起作用,因为用户将无法使用鼠标选择任何文本; .SelectAll()调用将继续覆盖用户的文本选择.

在焦点/输入事件输入上调用BeginInvoke((Action)textbox.SelectAll)不起作用,因为它违反了上面的规则#2,它将继续覆盖用户对焦点的选择.

Judah Gabrie.. 107

首先,谢谢你的回答!共9个答案.谢谢.

坏消息:所有的答案都有些怪癖或者做得不对(或根本没有).我已经为您的每个帖子添加了评论.

好消息:我找到了一种让它发挥作用的方法.这个解决方案非常简单,似乎适用于所有场景(鼠标,选择文本,标记焦点等)

bool alreadyFocused;

...

textBox1.GotFocus += textBox1_GotFocus;
textBox1.MouseUp += textBox1_MouseUp;
textBox1.Leave += textBox1_Leave;

...

void textBox1_Leave(object sender, EventArgs e)
{
    alreadyFocused = false;
}


void textBox1_GotFocus(object sender, EventArgs e)
{
    // Select all text only if the mouse isn't down.
    // This makes tabbing to the textbox give focus.
    if (MouseButtons == MouseButtons.None)
    {
        this.textBox1.SelectAll();
        alreadyFocused = true;
    }
}

void textBox1_MouseUp(object sender, MouseEventArgs e)
{
    // Web browsers like Google Chrome select the text on mouse up.
    // They only do it if the textbox isn't already focused,
    // and if the user hasn't selected all text.
    if (!alreadyFocused && this.textBox1.SelectionLength == 0)
    {
        alreadyFocused = true;
        this.textBox1.SelectAll();
    }
}

据我所知,这会导致文本框的行为与Web浏览器的地址栏完全相同.

希望这有助于下一个试图解决这个看似简单的问题的人.

再次感谢,伙计们,所有的答案都帮助我走上了正确的道路.



1> Judah Gabrie..:

首先,谢谢你的回答!共9个答案.谢谢.

坏消息:所有的答案都有些怪癖或者做得不对(或根本没有).我已经为您的每个帖子添加了评论.

好消息:我找到了一种让它发挥作用的方法.这个解决方案非常简单,似乎适用于所有场景(鼠标,选择文本,标记焦点等)

bool alreadyFocused;

...

textBox1.GotFocus += textBox1_GotFocus;
textBox1.MouseUp += textBox1_MouseUp;
textBox1.Leave += textBox1_Leave;

...

void textBox1_Leave(object sender, EventArgs e)
{
    alreadyFocused = false;
}


void textBox1_GotFocus(object sender, EventArgs e)
{
    // Select all text only if the mouse isn't down.
    // This makes tabbing to the textbox give focus.
    if (MouseButtons == MouseButtons.None)
    {
        this.textBox1.SelectAll();
        alreadyFocused = true;
    }
}

void textBox1_MouseUp(object sender, MouseEventArgs e)
{
    // Web browsers like Google Chrome select the text on mouse up.
    // They only do it if the textbox isn't already focused,
    // and if the user hasn't selected all text.
    if (!alreadyFocused && this.textBox1.SelectionLength == 0)
    {
        alreadyFocused = true;
        this.textBox1.SelectAll();
    }
}

据我所知,这会导致文本框的行为与Web浏览器的地址栏完全相同.

希望这有助于下一个试图解决这个看似简单的问题的人.

再次感谢,伙计们,所有的答案都帮助我走上了正确的道路.


你应该将mouseUp中的`alreadyFocused = true;`移出if语句.因为如果您立即选择部分文本,则下一次单击将再次选择整个文本.

2> Duncan Smart..:

我找到了一个更简单的解决方案.它涉及使用异步启动SelectAll,Control.BeginInvoke以便在Enter和Click事件发生后发生:

在C#中:

private void MyTextBox_Enter(object sender, EventArgs e)
{
    // Kick off SelectAll asyncronously so that it occurs after Click
    BeginInvoke((Action)delegate
    {
        MyTextBox.SelectAll();
    });
}

在VB.NET中(感谢Krishanu Dey)

Private Sub MyTextBox_Enter(sender As Object, e As EventArgs) Handles MyTextBox.Enter 
    BeginInvoke(DirectCast(Sub() MyTextBox.SelectAll(), Action)) 
End Sub


在.Net 4.0中你可以这样做:BeginInvoke((Action)MyTextBox.SelectAll);
最聪明的答案我找到了..非常感谢..对于VB.net这里是解决方案..`Private Sub MyTextBox_Enter(sender as Object,e As EventArgs)处理MyTextBox.Enter BeginInvoke(DirectCast(Sub()MyTextBox. SelectAll(),Action))End Sub`
不幸的是,BeginInvoke不适用于我(无疑由于我的灾难性尘埃版本的Dot网络).预先"控制".它没有帮助,也没有预先设置TextBox本身的名称.一个人,苍白地游荡......
请注意,此解决方案的行为与问题中描述的完全不同.特别是`鼠标按下并在文本框中拖动应该只选择我用鼠标突出显示的文本.不能按预期工作.但仍然是最短,最优雅的解决方案:)

3> nzhenry..:

您的解决方案很好,但在一个特定情况下失败.如果通过选择文本范围而不是单击来给TextBox焦点,则alreadyFocussed标志不会设置为true,因此当您再次单击TextBox时,将选中所有文本.

这是我的解决方案版本.我还将代码放入一个继承TextBox的类中,因此逻辑很好地隐藏起来了.

public class MyTextBox : System.Windows.Forms.TextBox
{
    private bool _focused;

    protected override void OnEnter(EventArgs e)
    {
        base.OnEnter(e);
        if (MouseButtons == MouseButtons.None)
        {
            SelectAll();
            _focused = true;
        }
    }

    protected override void OnLeave(EventArgs e)
    {
        base.OnLeave(e);
        _focused = false;
    }

    protected override void OnMouseUp(MouseEventArgs mevent)
    {
        base.OnMouseUp(mevent);
        if (!_focused)
        {
            if (SelectionLength == 0)
                SelectAll();
            _focused = true;
        }
    }
}


+1自定义文本框建议和完美的解决方案!

4> 小智..:

这有点笨拙,但在你的点击事件中,请使用SendKeys.Send( "{HOME}+{END}" );.


考虑到许多反病毒程序拦截并阻止SEND KEYS恶意攻击.这不是一个很好的解决方案.
推荐阅读
mobiledu2402851203
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有