WindowsFormsApplicationBase SplashScreen 使登录表单忽略按键,直到我单击它 - 如何调试?

发布于 2024-10-09 11:48:23 字数 1206 浏览 0 评论 0原文

我的 WinForms 应用程序有一个简单的模式登录表单,在启动时通过 ShowDialog() 调用。当我从 Visual Studio 内部运行时,一切正常。我只需输入我的用户 ID,按 Enter 键即可登录。

但是当我直接运行发布版本时,一切看起来都很正常(登录表单处于活动状态,用户 ID MaskedEditBox 中有一个闪烁的光标),但是在我单击登录表单上的某个位置之前,所有按键都会被忽略。如果您习惯于通过键盘完成所有操作,则非常烦人。

我尝试跟踪事件处理程序,并直接用代码设置焦点,但无济于事。

关于如何调试此问题(在 Visual Studio 之外)或失败的任何建议 - 可能的解决方法?

编辑

这是我的主窗体中的调用代码:

    private void OfeMainForm_Shown(object sender, EventArgs e)
    {
        OperatorLogon();
    }

    private void OperatorLogon()
    {
        // Modal dialogs should be in a "using" block for proper disposal
        using (var logonForm = new C21CfrLogOnForm())
        {
            var dr = logonForm.ShowDialog(this);

            if (dr == DialogResult.OK)
                SaveOperatorId(logonForm.OperatorId);
            else
                Application.Exit();
        }
    }

编辑2

认为这不相关,但我正在使用Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase 因为它的启动屏幕和 SingleInstanceController 支持。

我只是注释掉了启动屏幕代码,问题就消失了。因此,这就开辟了一条全新的探究路线...

编辑 3

更改了标题以反映对问题的更好理解

My WinForms app has a simple modal login form, invoked at startup via ShowDialog(). When I run from inside Visual Studio, everything works fine. I can just type in my User ID, hit the Enter key, and get logged in.

But when I run a release build directly, everything looks normal (the login form is active, there's a blinking cursor in the User ID MaskedEditBox), but all keypresses are ignored until I click somewhere on the login form. Very annoying if you are used to doing everything from the keyboard.

I've tried to trace through the event handlers, and to set the focus directly with code, to no avail.

Any suggestions how to debug this (outside of Visual Studio), or failing that - a possible workaround?

Edit

Here's the calling code, in my Main Form:

    private void OfeMainForm_Shown(object sender, EventArgs e)
    {
        OperatorLogon();
    }

    private void OperatorLogon()
    {
        // Modal dialogs should be in a "using" block for proper disposal
        using (var logonForm = new C21CfrLogOnForm())
        {
            var dr = logonForm.ShowDialog(this);

            if (dr == DialogResult.OK)
                SaveOperatorId(logonForm.OperatorId);
            else
                Application.Exit();
        }
    }

Edit 2

Didn't think this was relevant, but I'm using Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase for it's splash screen and SingleInstanceController support.

I just commented out the splash screen code, and the problem has disappeared. So that's opened up a whole new line of inquiry...

Edit 3

Changed title to reflect better understanding of the problem

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沧桑㈠ 2024-10-16 11:48:23

UI焦点/重画/等等。使用远程调试来调试问题通常相当简单。即使用第二台 PC(虚拟机就足够了)来运行您的应用程序。

有关详细信息,请参阅这篇 MSDN 文章

UI focus/redraw/etc. issues usually are rather straightforward to debug by using remote-debugging. I.e. use a second PC (virtual is just enough) where your application runs.

See this MSDN article for details.

烙印 2024-10-16 11:48:23

在后面的表单代码中运行它。它会通过提供控件的类型和名称来告诉您哪个控件具有焦点。在 form_shown 中运行它,因为它是表单加载过程中的最后一个事件。

private void Form1_Shown(object sender, EventArgs e)
{
    Control control = FindFocusedControl(this);
    MessageBox.Show("The focused control " + control.Name + " is of type " + control.GetType());
}
public static Control FindFocusedControl(Control control)
{
    var container = control as ContainerControl;
    while (container != null)
    {
        control = container.ActiveControl;
        container = control as ContainerControl;
    }
    return control;
}

如果此后答案不明显,请告诉我们您得到了什么。

Run this in your form code behind. It will tell you which control has focus by giving you the type and name of the control. Run it in form_shown because its the last event in the form load process.

private void Form1_Shown(object sender, EventArgs e)
{
    Control control = FindFocusedControl(this);
    MessageBox.Show("The focused control " + control.Name + " is of type " + control.GetType());
}
public static Control FindFocusedControl(Control control)
{
    var container = control as ContainerControl;
    while (container != null)
    {
        control = container.ActiveControl;
        container = control as ContainerControl;
    }
    return control;
}

If the answer isn't obvious after that, tell us what you get.

心病无药医 2024-10-16 11:48:23

我找到了一个黑客...呃...我的意思是...解决方法,可以解决问题。该解决方案隐藏在 的评论之一中这个答案(感谢 P. Brian Mackey 提供了相关问题的链接!)

解决方法是在显示启动屏幕时最小化主窗口,然后在显示登录之前将其 WindowState 设置回正常形式。

在下面的代码中,请参阅用“HACK”注释的行。

public class SingleInstanceController : WindowsFormsApplicationBase
{
    public SingleInstanceController()
    {
        this.IsSingleInstance = true;
    }

    /// <summary>
    /// When overridden in a derived class, allows a designer to emit code that 
    /// initializes the splash screen.
    /// </summary>
    protected override void OnCreateSplashScreen()
    {
        this.SplashScreen = new SplashScreen();
    }

    /// <summary>
    /// When overridden in a derived class, allows a designer to emit code that configures 
    /// the splash screen and main form.
    /// </summary>
    protected override void OnCreateMainForm()
    {
        // SplashScreen will close after MainForm_Load completed
        this.MainForm = new OfeMainForm();

        // HACK - gets around problem with logon form not having focus on startup
        // See also OfeMainForm_Shown in OfeMainForm.cs
        this.MainForm.WindowState = FormWindowState.Minimized;
    }
}


public partial class OfeMainForm : Form
{
    // ...

    private void OfeMainForm_Shown(object sender, EventArgs e)
    {
        // HACK - gets around problem with logon form not having focus on startup
        // See also OnCreateMainForm in Program.cs
        this.WindowState = FormWindowState.Normal;

        OperatorLogon();
    }

    // ...

}

这目前有效,但我想知道是否应该从 SingleInstanceController 显式打开登录表单,而不是从我的主表单。

I've found a hack...er...I mean...workaround, that fixes the problem. The solution was buried in one of the comments of this answer (thanks, P. Brian Mackey, for providing the link to the related question!)

The workaround is to minimize the main window while the splash screen is displayed, then set it's WindowState back to Normal before showing the login form.

In the code below, see the lines commented with "HACK".

public class SingleInstanceController : WindowsFormsApplicationBase
{
    public SingleInstanceController()
    {
        this.IsSingleInstance = true;
    }

    /// <summary>
    /// When overridden in a derived class, allows a designer to emit code that 
    /// initializes the splash screen.
    /// </summary>
    protected override void OnCreateSplashScreen()
    {
        this.SplashScreen = new SplashScreen();
    }

    /// <summary>
    /// When overridden in a derived class, allows a designer to emit code that configures 
    /// the splash screen and main form.
    /// </summary>
    protected override void OnCreateMainForm()
    {
        // SplashScreen will close after MainForm_Load completed
        this.MainForm = new OfeMainForm();

        // HACK - gets around problem with logon form not having focus on startup
        // See also OfeMainForm_Shown in OfeMainForm.cs
        this.MainForm.WindowState = FormWindowState.Minimized;
    }
}


public partial class OfeMainForm : Form
{
    // ...

    private void OfeMainForm_Shown(object sender, EventArgs e)
    {
        // HACK - gets around problem with logon form not having focus on startup
        // See also OnCreateMainForm in Program.cs
        this.WindowState = FormWindowState.Normal;

        OperatorLogon();
    }

    // ...

}

This is working for now, but I'm wondering if I should explicitly open the Logon form from the SingleInstanceController, rather than from my main form.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文