wpf 显示加载窗口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13835790/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 06:34:34  来源:igfitidea点击:

Show loading window

c#.netwpfwindowloading

提问by FukYouAll

My application in WPF loads external resources, so I want to show a loading form while the program is loading.

我在 WPF 中的应用程序加载外部资源,所以我想在程序加载时显示一个加载表单。

I tried to create the form, and show before the loading code, and close when loading ended.

我尝试创建表单,并在加载代码之前显示,并在加载结束时关闭。

private void Window_Loaded(object sender, RoutedEventArgs e)
{
     LoadForm lf = new LoadForm();
     lf.Visibility = Visibility.Visible;

     // Al code that delays application loading

     lf.Close();
}

But the only thing I get is that the form is showed when loading progress is complete and immediately closes.

但我唯一得到的是当加载进度完成并立即关闭时显示表单。

I think that I need to use System.Threading but not sure.

我认为我需要使用 System.Threading 但不确定。

Thanks.

谢谢。

NoteI load all application external resources in Window_Loaded() method and not in the main class method.

注意我在 Window_Loaded() 方法中而不是在主类方法中加载所有应用程序外部资源。

回答by Mark Hall

You should look at this MSDN article on creating a SplashScreenin WPF. Essentially you add the Image you want to show to your project and set the Build Action to SplashScreen it will show when your program starts and disappear when your Main Application Window is shown.

您应该查看有关在 WPF 中创建SplashScreen 的这篇 MSDN 文章。本质上,您将要显示的图像添加到您的项目中,并将构建操作设置为 SplashScreen,它将在您的程序启动时显示并在您的主应用程序窗口显示时消失。



You could also try importing the System.ComponentModelClass and use BackgroundWorkerto Show your Loading Form, it will allow you to retain responsiveness of your UI.

您还可以尝试导入System.ComponentModel类并使用BackgroundWorker来显示您的加载表单,这将允许您保留 UI 的响应能力。

public partial class MainWindow : Window
{
    Window1 splash;
    BackgroundWorker bg;
    public MainWindow()
    {

        InitializeComponent();

        bg = new BackgroundWorker();
        bg.DoWork += new DoWorkEventHandler(bg_DoWork);
        bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);

    }

    void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        splash.Hide();
    }

    void bg_DoWork(object sender, DoWorkEventArgs e)
    {
        System.Threading.Thread.Sleep(10000);
    }


    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        splash = new Window1();
        splash.Show();
        bg.RunWorkerAsync();
    }
}

回答by Haris Hasan

You should put your time consuming code in a background thread (for that you can use BackgroundWorker, Task or Async Await, depending on your dot net framework version)

您应该将耗时的代码放在后台线程中(为此您可以使用 BackgroundWorker、Task 或 Async Await,具体取决于您的 dot net framework 版本)

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    LoadForm lf = new LoadForm();
    lf.Visibility = Visibility.Visible;
    //start the time consuming task in another thread
}


HeavyTaskCompleteEvent()
{
     lf.Close();
}

Also look out for the best way to show loading screen. You can show some animation in the main window as well. I don't think showing a form is the best way.

还要注意显示加载屏幕的最佳方式。您也可以在主窗口中显示一些动画。我不认为展示表格是最好的方式。

回答by Florian Gl

I made a Loader class a while ago you could use. It shows a Window while doing your loading-method, closes it when completed and gives you the output of the method:

前段时间我做了一个 Loader 类,你可以使用。它在执行加载方法时显示一个窗口,完成后关闭它并为您提供方法的输出:

public class Loader<TActionResult>:FrameworkElement
{
    private Func<TActionResult> _execute;
    public TActionResult Result { get; private set; }
    public delegate void OnJobFinished(object sender, TActionResult result);
    public event OnJobFinished JobFinished;

    public Loader(Func<TActionResult> execute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
    }

    private Window GetWaitWindow()
    {
        Window waitWindow = new Window { Height = 100, Width = 200, WindowStartupLocation = WindowStartupLocation.CenterScreen, WindowStyle = WindowStyle.None };
        waitWindow.Content = new TextBlock { Text = "Please Wait", FontSize = 30, FontWeight = FontWeights.Bold, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center };

        return waitWindow;
    }

    public void Load(Window waitWindow = null)
    {
        if (waitWindow == null)
        {
            waitWindow = GetWaitWindow();
        }
        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += delegate
        {
            Dispatcher.BeginInvoke(new Action(delegate { waitWindow.ShowDialog(); }));
            Result = _execute();
            Dispatcher.BeginInvoke(new Action(delegate() { waitWindow.Close(); }));
        };
        worker.RunWorkerCompleted += delegate
        {
            worker.Dispose();
            if (JobFinished != null)
            {
                JobFinished(this, Result);
            }
        };
        worker.RunWorkerAsync();
    }
}

How to use it:

如何使用它:

Loader<TResult> loader = new Loader<TResult>(MethodName);
loader.JobFinished += new Loader<TResult>.OnJobFinished(loader_JobFinished);
loader.Load();

void loader_JobFinished(object sender, TResult result)
{
    // do whatever you want with your result here
}