为什么我的 SplashScreen 不显示标签(文本)
Why does my SplashScreen Not show a Label (Text)
我有一个名为 SpalshScreen.cs
的 WinForm
,带有一个简单的标签,Text
属性 设置为 "Data Loading..."。标签在表单中居中。我还定义了一个名为 DoClose()
方法的 public 方法。
我的 MainForm.Form_Load
方法包含:
Hide();
SplashScreen form = new SplashScreen();
form.Show();
// Simulate Doing Database Table Load(s)
Thread.Sleep(5000);
form.DoClose();
Show();
然而,当我 运行 时,我的启动画面确实出现了,但是标签文本应该是它只显示一个浅色框。
如果我将 form.Show();
更改为 form.ShowDialog();
,文本会正确显示,但主循环会暂停,直到我关闭 Splash Window。
在闪屏表单中使用计时器而不是 thread.sleep(例如 5 秒后关闭闪屏),并设置它的关闭事件。
var form = new SplashScreen();
form.Closed += (s,e)=>{
Show();
}
form.Show();
经过反复试验...诀窍是不阻塞 UI 线程,如@Servy 所说。
Form_Load 方法需要更改为:
Hide();
Splash.Show();
// Everything after this line must be Non UI Thread Blocking
Task task = new Task(LoadDataAsync);
task.Start();
task.Wait();
Splash.DoClose();
Show();
我创建了一个 LoadDataAsync 方法来处理其他所有事情:
private async void LoadDataAsync()
{
await Context.Employees.LoadAsync();
await Context.Customers.LoadAsync();
// The Invoke/Action Wrapper Keeps Modification of UI Elements from
// complaining about what thread they are on.
if (EmployeeDataGridView.InvokeRequired)
{
Action act = () => EmployeeBindingSource.DataSource = Context.Employees.Local.ToBindingList();
EmployeeDataGridView.Invoke(act);
}
if (CustomerComboBox.InvokeRequired)
{
Action act = () =>
{
CustomerBindingSource.DataSource = GetCustomerList();
CustomerComboBox.SelectedIndex = -1;
};
CustomerComboBox.Invoke(act);
}
}
我还将我使用的任何私有字段和私有方法设置为静态。
我有一个名为 SpalshScreen.cs
的 WinForm
,带有一个简单的标签,Text
属性 设置为 "Data Loading..."。标签在表单中居中。我还定义了一个名为 DoClose()
方法的 public 方法。
我的 MainForm.Form_Load
方法包含:
Hide();
SplashScreen form = new SplashScreen();
form.Show();
// Simulate Doing Database Table Load(s)
Thread.Sleep(5000);
form.DoClose();
Show();
然而,当我 运行 时,我的启动画面确实出现了,但是标签文本应该是它只显示一个浅色框。
如果我将 form.Show();
更改为 form.ShowDialog();
,文本会正确显示,但主循环会暂停,直到我关闭 Splash Window。
在闪屏表单中使用计时器而不是 thread.sleep(例如 5 秒后关闭闪屏),并设置它的关闭事件。
var form = new SplashScreen();
form.Closed += (s,e)=>{
Show();
}
form.Show();
经过反复试验...诀窍是不阻塞 UI 线程,如@Servy 所说。
Form_Load 方法需要更改为:
Hide();
Splash.Show();
// Everything after this line must be Non UI Thread Blocking
Task task = new Task(LoadDataAsync);
task.Start();
task.Wait();
Splash.DoClose();
Show();
我创建了一个 LoadDataAsync 方法来处理其他所有事情:
private async void LoadDataAsync()
{
await Context.Employees.LoadAsync();
await Context.Customers.LoadAsync();
// The Invoke/Action Wrapper Keeps Modification of UI Elements from
// complaining about what thread they are on.
if (EmployeeDataGridView.InvokeRequired)
{
Action act = () => EmployeeBindingSource.DataSource = Context.Employees.Local.ToBindingList();
EmployeeDataGridView.Invoke(act);
}
if (CustomerComboBox.InvokeRequired)
{
Action act = () =>
{
CustomerBindingSource.DataSource = GetCustomerList();
CustomerComboBox.SelectedIndex = -1;
};
CustomerComboBox.Invoke(act);
}
}
我还将我使用的任何私有字段和私有方法设置为静态。