带进度条的 WPF 启动画面 [英] WPF SplashScreen with ProgressBar

查看:78
本文介绍了带进度条的 WPF 启动画面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 WPF 项目,项目向导添加了一个启动画面.在同一个启动画面上,我想添加一个进度条样式表.有人知道如何做到这一点吗?

I have a WPF project, with a splash screen added by the Project Wizard. On the same splash screen, I want to add a progress bar style meter. Does someone have any idea how to do this?

推荐答案

这是我的方案.我这样做的动机是我不想让初始化代码在 UI 线程上运行,通常我希望在我的 App 类(而不是启动画面)上运行初始化代码.

Here is my scheme for doing this. My motivation for doing it this way is that I don't want to have the initialization code running on the UI Thread, and normally I want the initialization code on my App class (not a Splash screen).

基本上,我将应用程序 StartupUri 设置为我的启动画面,这让球滚动起来.

Basically, I set the App StartupUri to my splash screen, which gets the ball rolling.

在初始屏幕上,我在应用程序上调用了一个委托.这是在工作线程上运行的.在启动画面中,我处理 EndInvoke,并关闭窗口.

On the splash screen, I invoke a delegate back on the application. This is run on a worker thread. In the splash screen, I handle the EndInvoke, and close the Window.

在应用程序初始化委托中,我完成了工作,最后,创建并打开了正常的主窗口.在工作负荷期间,我也有一个关于 Slash 的方法,可以让我更新进度.

In the application initialization delegate, I do the work, and at the end, create and open the normal main Window. During the work load, I also have a method on Slash that allows me to update progress.

好的,代码相当短,不包括主窗口代码(不受所有这些影响),但它会与匿名代表一起躲避,所以请仔细阅读,最好在调试器.

OK,the code is fairly short, and doesn't include the main window code (which is unaffected by all this), but it ducks and dives with anonymous delegates, so read it carefully, and ideally play with it in the debugger.

这是代码....

<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();
        });           
    }
}

splash xaml(实际上,这里没什么有趣的......)

splash xaml (actually, nothing too interesting here...)

<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; });           
    }
}

由于工作是在工作线程上完成的,进度条会很好地更新,并且您在启动屏幕上的任何动画都会使娱乐持续进行.

As the work is done on a worker thread, the progress bar will update nicely, and any animation you have on the splash screen will keep the entertainment rolling.

这篇关于带进度条的 WPF 启动画面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆