单击winform应用程序中的按钮后,如何将焦点返回到上次使用的控件?
我正在Windows窗体应用程序(C#)上工作,在该窗体中,用户正在窗体中输入数据。在编辑表单中的数据时,用户可以随时单击表单上的按钮之一以执行某些操作。默认情况下,焦点会移到单击的按钮上,因此用户必须重新单击要编辑的控件,才能继续修改表单上的数据。我需要做的是在处理完按钮单击事件后,将焦点返回到上次编辑的控件。这是一个示例屏幕截图,说明了我在说什么:
用户可以在textbox1,textbox2,textbox3等中输入数据,然后单击按钮。我需要按钮才能将焦点返回到单击该按钮之前最近拥有焦点的控件。
我想知道是否有人能比我想出的更好的方法来实现此功能。这是我现在正在做的事情:
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方法。然后,当单击按钮时,焦点将返回到单击按钮之前具有焦点的控件。有人对此有更好的解决方案吗?
解决方案
回答
实现看起来足够好-我想知道的是为什么我们首先要这样做?将焦点循环回到第一个条目是否可取?最后一个文本框中的数据是否具有延展性,一旦他们单击该按钮就可以"记住"该数据?还是我们有按钮对特定文本框数据进行的某种操作-在那种情况下,焦点不应该放在后续控件上吗?
我有兴趣了解我们为什么首先要这样做。
回答
我想你在做什么很好。我唯一想改进的就是将每个控件在访问时存储到堆栈中。这将为我们提供访问内容的完整时间表。
回答
方法看起来不错。如果要避免在添加的每个控件中添加事件处理程序,则可以创建一个递归例程,以将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 }
回答
对于"简单性",可以尝试一下。
public Form1() { InitializeComponent(); foreach (Control ctrl in Controls) { if (ctrl is TextBox) { ctrl.Enter += delegate(object sender, EventArgs e) { _lastEnteredControl = (Control)sender; }; } } }
那么我们不必担心手动装饰每个文本框(也不必担心一个)。
回答
是的,我承认这个要求有点不寻常。用户将进入此应用程序的某些信息存在于对旧文档的扫描中,这些旧文档位于几个不同的存储库中。这些按钮有助于查找和打开这些旧文档。当用户决定拉出包含更多信息以输入表单的文档时,很难预测用户将在表单上的位置。尽管存在这些时髦的情况,但目的是使UI顺利进行。
回答
我们可以执行以下操作
将按钮更改为标签,使其看起来像一个按钮。标签将永远不会成为焦点,我们不必执行所有额外的编码。