单击winform应用程序中的按钮后,如何将焦点返回到上次使用的控件?

我正在使用Windows窗体应用程序(C#),用户在表单中输入数据。 在编辑表单中的数据时,用户可以单击表单上的其中一个按钮来执行某些操作。 默认情况下,焦点转到单击的按钮,因此用户必须单击返回要编辑的控件才能继续修改表单上的数据。 我需要做的是在处理完按钮点击事件后将焦点返回到最后编辑的控件。 这是一个示例截图,说明了我在说什么:

示例App屏幕截图

用户可以在textbox1,textbox2,textbox3等中输入数据,然后单击按钮。 我需要按钮将焦点返回到最近在单击按钮之前具有焦点的控件。

我想知道是否有人比我想出的更好地实现这个function。 这就是我现在正在做的事情:

public partial class Form1 : Form { Control _lastEnteredControl; private void textBox_Enter(object sender, EventArgs e) { _lastEnteredControl = (Control)sender; } private void button1_Click(object sender, EventArgs e) { MessageBox.Show("Do something here"); _lastEnteredControl.Focus(); } } 

所以我们这里基本上是一个指向最后输入控件的类变量。 表单上的每个文本框都已设置,因此当控件获得焦点时会触发textBox_Enter方法。 然后,当单击该按钮时,焦点将返回到单击按钮之前具有焦点的控件。 有人有更优雅的解决方案吗?

对于一点’简单’可能会尝试。

 public Form1() { InitializeComponent(); foreach (Control ctrl in Controls) { if (ctrl is TextBox) { ctrl.Enter += delegate(object sender, EventArgs e) { _lastEnteredControl = (Control)sender; }; } } } 

那么你不必担心手动装饰每个文本框(或者忘记一个文本框)。

您可以执行以下操作

将按钮更改为标签,使其看起来像一个按钮。 标签永远不会聚焦,您不必进行所有额外编码。

我觉得你做的很好。 我唯一能想到的就是在访问它们时将每个控件存储到一个堆栈中。 这将为您提供完整的访问时间。

你的方法很好看。 如果要避免必须为添加的每个控件添加事件处理程序,可以创建一个递归例程,将GotFocus侦听器添加到表单中的每个控件。 这适用于表单中的任何类型的控件,但您可以调整它以满足您的需要。

 private void Form_OnLoad(object obj, EventArgs e) { AddGotFocusListener(this); } private void AddGotFocusListener(Control ctrl) { foreach(Control c in ctrl.Controls) { c.GotFocus += new EventHandler(Control_GotFocus); if(c.Controls.Count > 0) { AddGotFocusListener(c); } } } private void Control_GotFocus(object obj, EventArgs e) { // Set focused control here } 

你的实现看起来很好 – 我想知道的是你为什么要首先做这个? 焦点重新回到第一个条目不是更好吗? 最后一个文本框中的数据是否具有可塑性,一旦他们点击按钮就会“记住”? 或者你有一些按钮对特定文本框数据执行的操作 – 在这种情况下,焦点不应该转移到后续控件吗?

我很想知道你为什么要这样做。

是的,我承认这个要求有点不寻常。 用户将进入此应用程序的一些信息存在于扫描几个不同存储库中的旧文档中。 按钮有助于查找和打开这些旧文档。 当用户决定提取包含更多信息的文档进入表单时,很难预测用户在表单上的位置。 尽管存在这些时髦的情况,但目的是使UI流畅。

创建一个名为CustomTextBox的类,该类inheritance自TextBox。 它有一个名为stack的静态变量。 当文本框失去焦点时,推入堆栈。 当您想要找到最后一个聚焦控件时,只需从堆栈中弹出第一个项目。 确保清除静态Stack变量。