使用窗口作为加载屏幕

时间:2016-10-06 09:41:37

标签: c# wpf xaml dynamic-splash-screen

我无法直接找到任何解决我的问题的方法。 我正在尝试制作一个动画gif作为加载屏幕,用于我的程序中加载时间过长的几个地方。

我让它在初创公司工作但是一旦我再次尝试使用它就会崩溃我的程序。我从来没有完全理解整个线程,所以我的代码可能出错了。

[编辑] 我想要的是在重型方法运行时让加载屏幕发生时让我们说它从数据库获取所有数据或只是一个简单的Thread.Sleep(# ###)并且在这一刻我想要一个动态的闪屏运行,这个屏幕是我的secound窗口,上面有一个GIF动画。我得到了窗口和gif运行。

我将要访问的Windows是

  • MainWindow.xaml
  • Loading.xaml
  • 的App.xaml

Loading.xaml

此页面上唯一的内容是使用WpfAnimatedGif包的动画gif。窗户的其余部分是透明的。

    public partial class Loading : Window, ISplashScreen
    {
    public Loading()
    {
        InitializeComponent();
    }

    public void LoadStart()
    {
        Dispatcher.Invoke((Action)delegate()
        {
            //this.UpdateMessageTextBox.Text = message;
        });
    }

    public void LoadComplete()
    {
        Dispatcher.InvokeShutdown();
    }
    }

    public interface ISplashScreen
    {
       void LoadStart();
       void LoadComplete();
    }
    }

的App.xaml

    public partial class App : Application
        {
            public static ISplashScreen splashScreen;

            private ManualResetEvent ResetSplashCreated;
            private Thread SplashThread;
            protected override void OnStartup(StartupEventArgs e)
            {
                // ManualResetEvent acts as a block. It waits for a signal to be set.
                ResetSplashCreated = new ManualResetEvent(false);

                // Create a new thread for the splash screen to run on
                SplashThread = new Thread(ShowSplash);
                SplashThread.SetApartmentState(ApartmentState.STA);
                SplashThread.IsBackground = true;
                SplashThread.Name = "Splash Screen";
                SplashThread.Start();

                // Wait for the blocker to be signaled before continuing. This is essentially the same as: while(ResetSplashCreated.NotSet) {}
                ResetSplashCreated.WaitOne();
                base.OnStartup(e);
            }

            private void ShowSplash()
            {
                // Create the window
                Loading animatedSplashScreenWindow = new Loading();
                splashScreen = animatedSplashScreenWindow;

                // Show it
                animatedSplashScreenWindow.Show();

                // Now that the window is created, allow the rest of the startup to run
                ResetSplashCreated.Set();
                System.Windows.Threading.Dispatcher.Run();
            }
        }
    }

MainWindow.xaml

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Action that takes time here
            App.splashScreen.LoadComplete();
        }

    private void _btnVisUKategorier_Click(object sender, RoutedEventArgs e)
    {
        App.splashScreen.LoadStart();
        FyldUKategorier();
        App.splashScreen.LoadComplete();
    }

PS:如果您知道任何更好的解决方案,我会尝试做同样的事情,请随时为其提供链接。

[编辑] 我改变了所以我不再使用app.xaml了,因为我在启动时不想要它我将代码移动到将要使用它的主窗口。

它现在不再崩溃,但它只是第一次显示我的窗口,除此之外的任何东西都没有显示任何内容。

[编辑-2] 我运行了一些测试并决定让窗口看起来更好,而且当我遇到确切问题所在的时候。 看起来上面的代码现在工作正常后我把它移动到我的Main而不是让它在App.xaml上运行。我删除了

    public void LoadStart()
    {
        Dispatcher.Invoke((Action)delegate()
        {
            //this.UpdateMessageTextBox.Text = message;
        });
    }

也来自Loading.xaml,因为我没有任何东西可供使用。在我关注的例子中,它用于更新页面上的标签。

问题似乎在于我安装的软件包应该向我展示动画gif。

    <Image gif:ImageBehavior.RepeatBehavior="Forever" gif:ImageBehavior.AnimatedSource="/img/Animated_ARKA_Loading.gif" />

新问题仍然是同一个项目

好的,所以下一个问题就是当我显示加载屏幕时,它第一次运行的时间是运行窗口是空的。

将加载到达我想要的点的修复程序在下面的解决方案中并且崩溃出现,因为我试图输入一个已关闭的线程。我以为我可以用方法启动它,所以我继续将它删除。

主窗口

    private void AnimatedLoading()
    {
        // ManualResetEvent acts as a block. It waits for a signal to be set.
        ResetSplashCreated = new ManualResetEvent(false);

        // Create a new thread for the splash screen to run on
        SplashThread = new Thread(ShowSplash);
        SplashThread.SetApartmentState(ApartmentState.STA);
        SplashThread.IsBackground = true;
        SplashThread.Name = "Splash Screen";
        SplashThread.Start();

        // Wait for the blocker to be signaled before continuing. This is essentially the same as: while(ResetSplashCreated.NotSet) {}
        ResetSplashCreated.WaitOne();

        FyldUKategorier();

        splashScreen.LoadComplete();
        SplashThread.Abort();
    }

    private void ShowSplash()
    {
        // Create the window
        Loading loading = new Loading();
        splashScreen = loading;

        // Show it
        loading.Show();

        // Now that the window is created, allow the rest of the startup to run
        ResetSplashCreated.Set();
        System.Windows.Threading.Dispatcher.Run();
    }

Loading.xaml

    public Loading()
    {
        InitializeComponent();
    }

    public void LoadComplete()
    {
        Dispatcher.InvokeShutdown();
    }
    }

    public interface ISplashScreen
    {
       void LoadComplete();
    }

0 个答案:

没有答案