构建此场景的最佳方式
我愿意:
创建类来管理“选择项目”窗口的数据(例如 MRU 列表、模板等),确保它们是独立的并且不需要与主线程交互。
将有关“当前”项目的信息存储在 Application 对象或单例对象中。
创建“选择项目”窗口以完全独立于主窗口进行操作。
设置“选择项目”窗口的“打开”和“创建”按钮以触发 Application.Open 命令,并将按钮上的 CommandParameter 绑定到包含要打开的文件名(或要打开的模板)的属性实例化)。
在窗口级别为Application.Open命令添加CommandBinding,以获取命令参数并在Application对象中设置当前项目。
在您的应用程序的启动代码中,立即生成一个线程以创建“选择项目”窗口,然后立即执行 {a Dispatcher.Invoke at ApplicationIdle 优先级,然后执行非常短的 Thread.Sleep} 几次,然后继续, 允许创建主窗口但使其最初不可见。
在主窗口中设置一个触发器,使其在第一次设置当前项目后可见。
下面是“选择项目”窗口中的Open 命令处理程序如何更新应用程序对象中的项目路径:
Application.Current.Dispatcher.Invoke(DispatcherPriority.Send, new Action(() =>
{
((App)Application.Current).CurrentProjectPath = e.Parameter;
}
以下是应用程序的启动代码:
public override void OnStartup(StartupEventArgs e)
{
new Thread(() => { new SelectProject().Show(); }).Start();
for(int i=0; i<10; i++)
{
Dispatcher.Invoke(DispatcherPriority.ApplicationIdle, () => {});
Thread.Sleep(20);
}
_guts = new MainWindowContent(); // probably a UserControl
_guts.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
_guts.Arrange(new Rect(0, 0, guts.DesiredSize.Width, guts.DesiredSize.Height));
_guts.SetBinding(VisibilityProperty,
new Binding { Source = this, Path="StartupFinished",
Converter = BoolToVisibiltyConverter.Instance });
_mainWindow = new MainWindow { Content = guts };
// Note: Title and other properties of MainWindow would be set in the XAML
}
注意额外的代码,以确保提前测量和安排胆量。
这里是设置当前项目路径的代码:
public string CurrentProjectPath
{
get { return _currentProjectPath; }
set
{
_currentProjectPath = value;
LoadProject();
_startupFinished = true;
OnPropertyChanged("StartupFinished");
}
}
此代码假定 XAML 绑定 _mainWindow 的 Visibility 属性
StartupFinished 是主窗口的 Visibility 属性绑定到的 DependencyProperty,但可以通过其他方式完成。
您能否通过这种方式看到更快的启动时间?
是的。
应该在主线程和其他线程上创建选择项目,反之亦然
您应该在主线程上创建 MainWindow,以便它与 Application 对象共享同一个 Dispatcher。这意味着“选择项目”必须在第二个线程中。
如果您需要使用 Win32 启动窗口来提高速度
可能没有必要。 WPF 本身的启动只需几分之一秒。但如果有必要,上述Application.Current.Dispatcher.Invoke 技术将起作用。
你知道 Blend 是如何实现它的启动窗口的吗?
没有