1

我有一个具有单个表单的 Windows 窗体应用程序(使用 .net / c#)。表单中没有从设计视图中放置的控件。

我也有自定义的“屏幕”类,它继承自用户控件类,并调整大小以完全适合表单。screen 类有许多事件处理程序,它们可以回调它们被添加到的表单。

我有一组 Screen 对象,它们以编程方式创建并作为控件添加到表单中。

foreach(Screen s in screens)
{
    Controls.Add(s);
}

单击任何屏幕上的下一个或上一个按钮间接调用表单中的适当方法(通过事件处理程序) - 然后表单通过 Visible 和 Enabled 属性处理切换屏幕的操作 - 即当需要删除屏幕或显示相应的 Visible 和 Enabled 属性分别设置为 false 和 true。

每个屏幕负责控制其显示内容的代码,表单代码只是处理从一个屏幕到另一个屏幕的流程。

因此,主窗体中下一个按钮处理程序的示例可能类似于

screens[currScreen].Visible = false;
screens[currScreen].Enabled = false;
currScreen++;
screens[currScreen].Visible = true;
screens[currScreen].Enabled = true;

这一切都很好,直到我尝试处理转义键。

我希望能够让用户按退出键退出应用程序。所以我的第一个想法是在以编程方式初始化每个屏幕时简单地添加以下代码......

screen[n].KeyUp += OnKeyUP;  // Where on key up is an event handler in the main form

这里的想法是我可以在控件中捕获事件并以调用的形式处理它......

private void OnKeyUp(object sender, KeyEventArgs e)
{
    if(e.KeyCode == Keys.Escape)
    { 
        this.Close();
    }
}

我知道这种类型的事件捕获在我已经用于某些鼠标操作的情况下有效,但它从不适用于键盘。所以我也尝试将事件处理程序放在我的屏幕类中,但这也不起作用。

我意识到也许控件没有焦点所以没有捕获键盘。所以我在表单中添加了以下调试代码......

        Console.WriteLine("Control: {0} - Focus = {1}", this.ToString(), this.Focused);
        foreach (Control c in this.Controls)
        {
            Console.WriteLine("Control: {0} - Focus = {1}", c.ToString(), c.Focused);
        }

没有什么有焦点,所以我不确定什么有焦点?

此外,我似乎无法获得任何关注,我尝试在控件和表单上调用 .Activate() 以及 .Focus() ,并且每当我重新运行上面的代码时,仍然没有任何焦点。

如果我删除将屏幕控件添加到表单的代码,然后运行上面的代码,则表单 KeyUp 事件检测到击键并且表单具有焦点。添加控件似乎可以阻止任何有焦点的东西。

任何人都知道如何让屏幕控件接收 keyup 事件,或者给他们焦点?我敢肯定,我做错了显然很愚蠢,但我现在正用头撞墙。

谢谢。

4

0 回答 0