在 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到主窗体,它就会自己显示。
大家好 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到主窗体,它就会自己显示。