在 Window 个表单之间切换似乎不起作用

Switching between Window Forms does not seem to work

大家好 Whosebug 社区!

所以我一直在开发一个应用程序,检查用户是否以 Login() 形式输入了有效凭据,然后它切换到 Intro_Sequence() 形式(其中一个 .mp4 文件以全屏模式播放)作为应用程序的一种美学补充。到目前为止一切顺利,没有任何问题。

问题在介绍结束后立即出现,据推测应用程序应该切换到第三种形式,称为 Main()

每当 Windows Media Player(又名 axWMPLib)更改其 PlayState 时,我都会执行检查以查看它是否已完成播放。

如果有,则调用Hide()事件隐藏当前窗体的window,则main.ShowDialog()应该打开第三个窗体

之后,我调用 Close() 事件来完全关闭前一个表单的 window。

目前的代码如下:

    public partial class Intro_Sequence : Form
    {
        public static string Username;
        public Intro_Sequence(string username)
        {
            InitializeComponent();
            Username = username;
            FormBorderStyle = FormBorderStyle.None;
            Bounds = Screen.PrimaryScreen.Bounds;
            TopMost = true;
            intro.uiMode = "none";
            intro.URL = AppDomain.CurrentDomain.BaseDirectory + "\Intro.mp4";
            intro.enableContextMenu = false;
            DisableMouseClicks();
        }
        private void DisableMouseClicks()
        {
            if (this.Filter == null)
            {
                this.Filter = new MouseClickMessageFilter();
                Application.AddMessageFilter(this.Filter);
            }
        }

        private MouseClickMessageFilter Filter;

        private const int LButtonDown = 0x201;
        private const int LButtonUp = 0x202;
        private const int LButtonDoubleClick = 0x203;

        public class MouseClickMessageFilter : IMessageFilter
        {

            public bool PreFilterMessage(ref System.Windows.Forms.Message m)
            {
                switch (m.Msg)
                {
                    case LButtonDown:
                    case LButtonUp:
                    case LButtonDoubleClick:
                        return true;
                }
                return false;
            }
        }

        private void Intro_Sequence_Load(object sender, EventArgs e)
        {
        }

        private void intro_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
        {
            if(intro.playState == WMPLib.WMPPlayState.wmppsMediaEnded)
            {
                Main main = new Main(Username);
                this.Hide();
                main.ShowDialog();
                this.Close();
            }
        }
    }

如您所见,我还添加了一个过滤器来阻止播放期间的点击,以免让用户暂停。

但是,当我执行这段代码时,它工作得很好,直到它完成视频然后突然关闭。

我尝试设置断点,一切似乎都很好。

它确实调用了我告诉它调用的所有内容,但表单甚至没有出现。

我还尝试了其他几种替代方法,比如根本不关闭表单,调用 Show() 而不是 ShowDialog(),甚至根本不隐藏它。

好像它要么冻结在那里,要么立即关闭,没有任何主窗体显示的迹象。

我还尝试从 Login() 调用 Main() 表单,它从那里完美运行。

真不知道怎么回事

如有任何帮助,我们将不胜感激。

这样的怎么样?

一共有三种形式。有一个 Login 表单(在本例中,它只是一个空表单 - 您可以通过单击红色 X 将其关闭)。它从 Main 表单中以模态方式弹出(而主表单是隐藏的)。

有一个 Splash 屏幕可以播放您的视频。我通过使用 await Task.Delay(4000); 暂停来伪造视频。 4 秒延迟后,我引发一个事件(相当于您的媒体播放器事件)。我所做的是从主窗体中以模态方式显示它。我将事件处理程序放在这种形式中;引发事件时,我关闭启动画面模式。该表单的整个(非设计器)代码如下所示(而且,由于此表单上没有控件,设计器代码非常精简):

public partial class SplashScreen : Form
{
    public event EventHandler SplashFinished;
    public SplashScreen()
    {
        InitializeComponent();
        this.SplashFinished += SplashScreen_SplashFinished;
    }

    private async void SplashScreen_Load(object sender, EventArgs e)
    {
        await Task.Delay(4000);
        SplashFinished?.Invoke(this, new EventArgs());
    }

    private void SplashScreen_SplashFinished(object sender, EventArgs e)
    {
        this.DialogResult = DialogResult.OK;
        this.Close();
    }
}

然后是 Main 表单。它以正常方式从 Program.cs:

开始
[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

我添加到该表单的唯一内容(来自开箱即用的代码)是:

private void Form1_Load(object sender, EventArgs e)
{
    this.Hide();
    var login = new LoginForm();
    //should really check this, but for now
    login.ShowDialog(this);
    var splash = new SplashScreen();
    splash.ShowDialog(this);
    this.Show();
}

因此,当应用程序启动时,会向用户显示登录表单(隐藏主表单)。他做了需要做的事情(结果在主窗体的 Form1_Load 处理程序中检查。

如果一切顺利,将创建一个新的 SplashScreen 表单并以模态方式显示。当它弹出时,视频开始(在这种情况下,视频只是一个异步计时器)。当视频结束时,SplashScreen 处理完成的 事件,并用它来关闭自己。

一旦控制returns到主窗体,它就会自己显示。