首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么在显示表单时TextBox中的文本会突出显示(选中)?

为什么在显示表单时TextBox中的文本会突出显示(选中)?
EN

Stack Overflow用户
提问于 2010-08-06 14:26:10
回答 5查看 87.5K关注 0票数 90

我有一个包含C#格式的TextBox的表单,我将其设置为一个字符串,如下所示:

代码语言:javascript
复制
textBox.Text = str;

当表单显示时,为什么文本框中的文本会突出显示/选中?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-08-06 14:36:30

文本框的TabIndex为0,TabStop设置为true。这意味着在显示窗体时,控件将获得焦点。

您可以为另一个控件提供0 TabIndex (如果有),并为文本框提供不同的制表符索引(>0),或者将文本框的TabStop设置为false以阻止这种情况发生。

票数 137
EN

Stack Overflow用户

发布于 2010-08-21 21:35:58

在Windows Forms中,TextBox的默认行为是在第一次通过Tab键进入焦点时突出显示所有文本,但在单击时则不突出显示所有文本。我们可以通过查看TextBoxOnGotFocus()覆盖在反射器中看到这一点:

代码语言:javascript
复制
protected override void OnGotFocus(EventArgs e)
{
    base.OnGotFocus(e);
    if (!this.selectionSet)
    {
        this.selectionSet = true;
        if ((this.SelectionLength == 0) && (Control.MouseButtons == MouseButtons.None))
        {
            base.SelectAll();
        }
    }
}

正是那个if语句导致了我们不喜欢的行为。此外,雪上加霜的是,每当重新赋值文本时,Text属性的setter都会盲目地重置selectionSet变量:

代码语言:javascript
复制
public override string Text
{
    get
    {
        return base.Text;
    }
    set
    {
        base.Text = value;
        this.selectionSet = false;
    }
}

因此,如果您有一个TextBox并使用Tab键进入它,所有的文本都将被选中。如果您单击它,突出显示将被移除,如果您重新使用tab键进入它,您的插入符号位置(和选择长度为零)将被保留。但是,如果我们以编程方式设置新的Text,并再次使用Tab键切换到TextBox,那么所有文本都将再次被选中。

如果你和我一样,觉得这种行为很烦人,而且前后不一致,那么有两种方法可以解决这个问题。

第一种,也可能是最简单的一种,就是通过在表单Load()上调用selectionSet并在Text发生更改时触发DeselectAll()的设置:

代码语言:javascript
复制
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    this.textBox2.SelectionStart = this.textBox2.Text.Length;
    this.textBox2.DeselectAll();
}

(DeselectAll()只是将SelectionLength设置为零。反转TextBoxselectionSet变量的实际上是SelectionStart。在上面的例子中,调用DeselectAll()是不必要的,因为我们将开始设置为文本的结尾。但是如果我们将它设置为任何其他位置,比如文本的开始,那么调用它是一个好主意。)

更持久的方法是通过继承创建具有所需行为的我们自己的TextBox:

代码语言:javascript
复制
public class NonSelectingTextBox : TextBox
{
    // Base class has a selectionSet property, but its private.
    // We need to shadow with our own variable. If true, this means
    // "don't mess with the selection, the user did it."
    private bool selectionSet;

    protected override void OnGotFocus(EventArgs e)
    {
        bool needToDeselect = false;

        // We don't want to avoid calling the base implementation
        // completely. We mirror the logic that we are trying to avoid;
        // if the base implementation will select all of the text, we
        // set a boolean.
        if (!this.selectionSet)
        {
            this.selectionSet = true;

            if ((this.SelectionLength == 0) && 
                (Control.MouseButtons == MouseButtons.None))
            {
                needToDeselect = true;
            }
        }

        // Call the base implementation
        base.OnGotFocus(e);

        // Did we notice that the text was selected automatically? Let's
        // de-select it and put the caret at the end.
        if (needToDeselect)
        {
            this.SelectionStart = this.Text.Length;
            this.DeselectAll();
        }
    }

    public override string Text
    {
        get
        {
            return base.Text;
        }
        set
        {
            base.Text = value;

            // Update our copy of the variable since the
            // base implementation will have flipped its back.
            this.selectionSet = false;
        }
    }
}

您可能不想直接调用base.OnGotFocus(),但这样我们就会失去Control基类中的有用功能。您可能不想在OnGotFocus()中随意使用selectionSet,而是每次都取消选择文本,但是如果用户使用Tab键离开并返回,我们就会失去用户的高亮显示。

丑陋?当然了。但事实就是如此。

票数 45
EN

Stack Overflow用户

发布于 2013-02-26 23:44:16

这个问题的答案对我解决类似的问题有很大帮助,但简单的答案只能与其他许多复杂的建议一起提示。只需在设置文本后将SelectionStart设置为0即可。问题解决了!

示例:

代码语言:javascript
复制
yourtextbox.Text = "asdf";
yourtextbox.SelectionStart = 0;
票数 32
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3421453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档