我正在处理用户在表单中输入数据的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方法。然后,当单击按钮时,焦点将返回到单击按钮之前具有焦点的控件。任何人都有更优雅的解决方案吗?
答案 0 :(得分:16)
对于一点'简单',也许试试。
public Form1()
{
InitializeComponent();
foreach (Control ctrl in Controls)
{
if (ctrl is TextBox)
{
ctrl.Enter += delegate(object sender, EventArgs e)
{
_lastEnteredControl = (Control)sender;
};
}
}
}
然后您不必担心手动装饰每个文本框(或者忘记一个文本框)。
答案 1 :(得分:2)
您可以执行以下操作
将按钮更改为标签,使其看起来像一个按钮。标签永远不会聚焦,您不必进行所有额外编码。
答案 2 :(得分:1)
我认为你所做的很好。我唯一能想到的就是在访问它们时将每个控件存储到一个堆栈中。这将为您提供所访问内容的完整时间表。
答案 3 :(得分:1)
你的方法看起来不错。如果要避免必须为添加的每个控件添加事件处理程序,可以创建一个递归例程,为表单中的每个控件添加一个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
}
答案 4 :(得分:0)
您的实施看起来足够好 - 我想知道的是您为什么要首先执行此操作?焦点重新回到第一个条目不是更好吗?最后一个文本框中的数据是否具有可塑性,一旦他们点击按钮就会“记住”?或者你有一些按钮对特定文本框数据进行的操作 - 在这种情况下,焦点不应该转移到后续控件上吗?
我很想知道你为什么要这样做。
答案 5 :(得分:0)
是的,我承认这个要求有点不寻常。用户将进入此应用程序的一些信息存在于扫描几个不同存储库中的旧文档中。按钮有助于查找和打开这些旧文档。当用户决定提取包含更多信息的文档进入表单时,很难预测用户在表单上的位置。尽管存在这些时髦的情况,但目的是使UI流畅。
答案 6 :(得分:0)
创建一个名为CustomTextBox的类,该类继承自TextBox。它有一个名为stack的静态变量。当文本框失去焦点推入堆栈时。当您想要找到最后一个聚焦控件时,只需从堆栈中弹出第一个项目。确保清除静态Stack变量。