我有一个 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/

10-17 00:21