【问题标题】:How to prevent text box from gaining focus unless clicked?除非单击,否则如何防止文本框获得焦点?
【发布时间】:2018-09-06 17:26:56
【问题描述】:

我有一个 WinForms 应用程序,它的顶部有一个 TextBox 控件(搜索框)。此 TextBox 在正常应用程序使用期间不断获得焦点,非常分散注意力。

我希望 TextBox 仅在用户明确点击它时才获得焦点。

我可以想到几个相当复杂的方法来完成这个:

  • 单击时将文本框的图像更改为文本框
  • 跟踪鼠标点击并根据鼠标状态转移焦点

我可以做一些更简单的事情来完成这个吗?


编辑以根据新的理解添加更好的问题描述

根据我收到的答案,我现在对导致此问题的原因有了一些更好的了解。当用户与我的应用程序交互时,各种操作会导致控件被禁用或完全消失。如果此时其中一个控件恰好具有焦点,则 Tab 键顺序中的下一个控件将获得焦点。

在添加相关文本框之前,我不知道“下一个控件”是什么。该应用程序在任何给定时间在屏幕上都有数百个控件,我很确定标签顺序从未被有意定义。不管以前是什么,都是无害的。添加搜索文本框后,该控件似乎总是以焦点结束。

这里有一个非常简单的例子来说明发生了什么:

public class Form1 : Form
{
    public Form1()
    {
        var button = new Button
        {
            Location = new System.Drawing.Point(159, 67),
            Size = new System.Drawing.Size(75, 23),
            TabIndex = 0,
            Text = @"Click me"
        };
        button.Click += (sender, args) => button.Enabled = false;

        var textBox = new TextBox
        {
            Location = new System.Drawing.Point(159, 142),
            Name = "textBox1",
            Size = new System.Drawing.Size(174, 20),
            TabIndex = 1
        };

        SuspendLayout();
        ClientSize = new System.Drawing.Size(486, 392);
        Controls.Add(textBox);
        Controls.Add(_button);
        ResumeLayout(false);
        PerformLayout();
    }
}

启动应用程序后,单击按钮将强制文本框获得焦点,因为它是 Tab 键顺序中的下一个。正如 Handbag Crab 在接受的答案中提到的那样,可以通过在文本框中设置 TabStop = false 来避免这种行为。

【问题讨论】:

  • 为什么文本框的焦点放在第一位?是因为人们正在浏览还是有代码不断设置焦点?
  • 正常情况下不应该得到焦点。也许你应该展示你的代码,你正在做的事情会设置焦点。
  • 我无法解释。应用程序中可以接收焦点的控件并不多,但有几个搜索框,具体取决于当时哪些视图处于活动状态。我刚刚添加了一个新的搜索框,它似乎在用户执行几乎任何操作后都会自动获得焦点。其他搜索框历来没有这个问题,我无法解释其中的区别。
  • 你不需要解释它,代码会为你做的。没有代码,你真正得到的最好的东西都是有根据的猜测。这是不正常的(正如您在其他控件中提到的那样),因此我们需要找出导致它的是什么原因
  • 也许你可以比较一下.designer.cs文件中其他文本框的设置方式,也许某些属性设置不同

标签: c# .net winforms


【解决方案1】:
textBox1.TabStop = false;

以上内容应该会阻止它从制表符接收焦点。

【讨论】:

  • 酷。很高兴能提供帮助。
【解决方案2】:

子类化 TextBox 和 WndProc 函数以捕获焦点消息并处理它。也许是这样的:

if (m.Msg == WM_MOUSEACTIVATE) {
    m.Result = (IntPtr)MA_NOACTIVATEANDEAT;
    return;
  }
  base.WndProc(ref m);

【讨论】:

  • 谢谢。虽然这不是解决方案,但这确实帮助我调试问题。我使用您的建议来查找 WM_SETFOCUS 消息,并在那里设置了一个断点。这使我能够更好地了解导致问题的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多