简体   繁体   English

在 WPF 和 C# 中构建 MainWindow() 和 InitializeComponent()

[英]MainWindow() and InitializeComponent() building in WPF and C#

This code is from my C# WPF application:此代码来自我的 C# WPF 应用程序:

public MainWindow()
{
    InitializeComponent();
    status("Getting dl links");
    getLinks();
}

The procedure getLinks currently displays a couple of links in a messagebox.过程getLinks当前在消息框中显示几个链接。 Those links are displayed in a messagebox before the WPF application becomes visible.在 WPF 应用程序变得可见之前,这些链接会显示在消息框中。 In this is case not a problem, but how would I show progress (like a progressbar) of any procedure I want to load at startup?在这种情况下不是问题,但我将如何显示我想在启动时加载的任何程序的进度(如进度条)?

Here is an example on how you can do it.这是一个关于如何做到这一点的示例。 To simplify it a bit, I added the controls directly in the MainWindow constructor, but I would prefer to do this with XAML.为了简化一点,我直接在MainWindow构造函数中添加了控件,但我更喜欢使用 XAML 来执行此操作。

public MainWindow()
{
    InitializeComponent();

    var progressBar = new ProgressBar();
    progressBar.Height = 40;
    progressBar.Width = 200;
    progressBar.Margin = new Thickness(100, 100, 100, 100);

    Task.Factory.StartNew(() =>
    {
        // getLinks();
        for (var i = 0; i < 5; i++)
        {
            Dispatcher.Invoke(new Action(() => { progressBar.Value += 20; }));

            Thread.Sleep(500);
        }
    });

    var stackPanel = new StackPanel();
    stackPanel.Children.Add(progressBar);

    Content = stackPanel;

}

I first add a ProgressBar somewhere on the interface to make it visible for this demo and then I add it to a new StackPanel , it could be any panel at all, in this case it doesn't matter.我首先在界面的某处添加一个ProgressBar以使其对这个演示可见,然后我将它添加到一个新的StackPanel ,它可以是任何面板,在这种情况下没关系。

To load the links on another thread, I create a new Task , this is a part of the TPL ( Task Parallel Library ) in .NET 4.0.为了在另一个线程上加载链接,我创建了一个新Task ,这是 .NET 4.0 中TPL任务并行库)的一部分。 In this case I am simulating that getLinks() takes 5 * 500 milliseconds to run and that it in fact is five links that will be loaded, hence 20% each iteration.在这种情况下,我模拟getLinks()需要 5 * 500 毫秒来运行,实际上它是要加载的五个链接,因此每次迭代需要 20%。

What I do then is that I add 20 to the progressBar value, which indicates that it increased with 20%.然后我所做的就是在progressBar值上加20 ,这表明它增加了 20%。

This line might confuse you a bit这条线可能会让你有点困惑

Dispatcher.Invoke(new Action(() => { progressBar.Value += 20; }));

But it is in fact quite common when you do cross-thread programming with GUI.但实际上,当您使用 GUI 进行跨线程编程时,这很常见。 So the problem is that you are on another thread here, we started of a Task that will run on a separate thread, and you cannot update your UI thread from another thread.所以问题是你在这里的另一个线程上,我们开始了一个将在一个单独的线程上运行的Task ,你不能从另一个线程更新你的 UI 线程。 So what you need is something called a Dispatcher , and this is accessable from within your Window -class.所以你需要的是一个叫做Dispatcher的东西,它可以从你的Window类中访问。

Then you Invoke an action on it, which means that you simply say "Run this piece of code on this thread for me".然后你在它上面Invoke一个动作,这意味着你只需说“为我在这个线程上运行这段代码”。

And if you want to display a MessageBox when everything is loaded, you can simply add a MessageBox.Show("Loaded;");如果你想在加载所有内容时显示一个MessageBox ,你可以简单地添加一个MessageBox.Show("Loaded;"); after the for -loop.for循环之后。

Any 'loading' tasks need to happen on a background thread (see the BackgroundWorker class - google for lots of examples).任何“加载”任务都需要在后台线程上进行(请参阅 BackgroundWorker class - google 获取大量示例)。 That way, the UI thread is free to show your window and update your window with status messages.这样,UI 线程就可以自由地显示您的 window 并使用状态消息更新您的 window。 Otherwise, the UI thread is blocked from doing anything until your loading is complete.否则,在加载完成之前,UI 线程将被阻止执行任何操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM