我有一个 WPF 项目,项目向导添加了一个启动画面。在同一个启动画面上,我想添加一个进度条样式表。有人知道如何做到这一点吗?
最佳答案
这是我这样做的方案。我这样做的动机是,我不想让初始化代码在UI线程上运行,并且通常我希望在我的App类(而不是启动屏幕)上运行初始化代码。
基本上,我将 App StartupUri
设置为我的启动画面,这让球滚动起来。
在初始屏幕上,我在应用程序上调用了一个委托(delegate)。这是在工作线程上运行的。在启动画面中,我处理 EndInvoke
并关闭窗口。
在应用程序初始化委托(delegate)中,我进行工作,最后,创建并打开普通的主窗口。在工作负载期间,我还有一个关于 Slash 的方法,可以让我更新进度。
好的,代码相当短,并且不包括主窗口代码(不受所有这些影响),但是它与匿名代表一起躲避和潜水,因此请仔细阅读,最好在调试器中使用它。
这是代码....
<Application x:Class="SplashScreenDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Splash.xaml">
<Application.Resources>
</Application.Resources>
</Application>
应用程序代码背后...
internal delegate void Invoker();
public partial class App : Application
{
public App()
{
ApplicationInitialize = _applicationInitialize;
}
public static new App Current
{
get { return Application.Current as App; }
}
internal delegate void ApplicationInitializeDelegate(Splash splashWindow);
internal ApplicationInitializeDelegate ApplicationInitialize;
private void _applicationInitialize(Splash splashWindow)
{
// fake workload, but with progress updates.
Thread.Sleep(500);
splashWindow.SetProgress(0.2);
Thread.Sleep(500);
splashWindow.SetProgress(0.4);
Thread.Sleep(500);
splashWindow.SetProgress(0.6);
Thread.Sleep(500);
splashWindow.SetProgress(0.8);
Thread.Sleep(500);
splashWindow.SetProgress(1);
// Create the main window, but on the UI thread.
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Invoker)delegate
{
MainWindow = new Window1();
MainWindow.Show();
});
}
}
飞溅
xaml
(实际上,这里没什么有趣的......)<Window x:Class="SplashScreenDemo.Splash"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Splash" Height="300" Width="300">
<Grid>
<TextBlock Height="21" Margin="91,61,108,0" VerticalAlignment="Top">Splash Screen</TextBlock>
<ProgressBar Name="progBar" Margin="22,122,16,109" Minimum="0" Maximum="1"/>
</Grid>
</Window>
飞溅代码隐藏...
public partial class Splash : Window
{
public Splash()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(Splash_Loaded);
}
void Splash_Loaded(object sender, RoutedEventArgs e)
{
IAsyncResult result = null;
// This is an anonymous delegate that will be called when the initialization has COMPLETED
AsyncCallback initCompleted = delegate(IAsyncResult ar)
{
App.Current.ApplicationInitialize.EndInvoke(result);
// Ensure we call close on the UI Thread.
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Invoker)delegate { Close(); });
};
// This starts the initialization process on the Application
result = App.Current.ApplicationInitialize.BeginInvoke(this, initCompleted, null);
}
public void SetProgress(double progress)
{
// Ensure we update on the UI Thread.
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Invoker)delegate { progBar.Value = progress; });
}
}
由于工作是在工作线程上完成的,进度条会很好地更新,并且您在启动屏幕上的任何动画都会使娱乐事件持续进行。
关于带进度条的 WPF 启动画面,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22026209/