带进度条的 WPF SplashScreen

标签 wpf splash-screen

我有一个 WPF 项目,其中有一个由项目向导添加的启动屏幕。在同一个启动屏幕上,我想添加一个进度条样式仪表。有人知道如何做到这一点吗?

最佳答案

这是我的计划。我这样做的动机是我不想在 UI 线程上运行初始化代码,通常我希望在我的 App 类(而不是启动屏幕)上运行初始化代码。

基本上,我将应用 StartupUri 设置为我的启动屏幕,这样就可以开始工作了。

在启动屏幕上,我调用应用程序上的委托(delegate)。这是在工作线程上运行的。在启动屏幕中,我处理 EndInvoke,并关闭窗口。

在应用程序初始化委托(delegate)中,我完成工作,最后创建并打开正常的主窗口。在工作期间,我在 Slash 上还有一个方法可以让我更新进度。

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

这是代码......

<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(实际上,这里没有什么太有趣的......)

<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 SplashScreen,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22026209/

相关文章:

c# - Web 浏览器中的透明内容

c# - 如何在 WPF 中为 TranslateTransform 和 ScaleTransform 设置动画

java - 如何在 Android 中制作一个点击后结束的介绍屏幕?

c# - 隐藏 WPF 窗口直到完全加载

android - 启动画面 - 首次共享首选项

java - 在多显示器上居中 Java 启动画面

wpf - 如何使用 WPF Toolkit 将多个图表与多个系列绑定(bind)?

c# - WPF 数据绑定(bind)到非属性

WPF 数据网格 : How to clear selection programmatically?

visual-studio - 如何在 Visual Studio 中为 Cordova 应用程序设置图标和初始屏幕?