线程,进度条操作方法 [英] Thread, progressbar howto

查看:58
本文介绍了线程,进度条操作方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 XslCompiledTransform 将 XML 文件转换为 HTML.XML文件没有那么短,所以转换浪费了很多时间.

I'm using XslCompiledTransform to transform XML file to HTML. XML file is not so short, so transformation is waste a lot of time.

我的代码:

 xslTransform.Transform(fi.FullName, TMP_TRANSFORMED_XML_PATH);
 webBrowser1.Navigate(TMP_TRANSFORMED_XML_PATH);

所以我想使用未绑定到表单的进度条或(更好的)进度图标(对话框?).

So I want to use progress-bar or (better) progress icon (dialog?) which is not bound to a form.

问题是我有两种形式.The 1st one has a list of items and a button, when item selected and button is pressed, 2nd form is shown (not modal), XML file transforms and it's shown in WebBrowser control.

The problem is that I have two forms. The 1st one has a list of items and a button, when item selected and button is pressed, 2nd form is shown (not modal), XML file transforms and it's shown in WebBrowser control.

在第二种形式的构造函数中,我调用 XslCompiledTransform.Load,初始化控件,然后调用 XslCompiledTransform.Transform().

In 2nd form constructor I call XslCompiledTransform.Load, initialize controls and then call XslCompiledTransform.Transform().

在第二个表单中,我也有按钮可以在第一个表单列表项之间导航.因此,当我按>"时,会选择第一个表单中的下一个元素,并重新加载第二个表单的元素 - 例如更改了一些文本,并为新的 XML 文件再次调用 XslCompiledTransform.Transform().

In a second form I also have buttons to navigate between 1st form list items. So when I press '>' then the next element from 1st form is selected, and 2nd form's elements are reloaded - e.g. some text changed and XslCompiledTransform.Transform() is called again for a new XML file.

那么,如何在每次加载第二个表单时组织进度条?

来自第一种形式:

private void OpenSecondForm()
{
    if (formTwo == null)
    {
            formTwo = new FormTwo(this, culture, params);
            formTwo .Show();
    }
    else
    {
            if (formTwo .IsDisposed)
            {
                formTwo = new FormTwo(this, culture, params);
                formTwo .Show();
            }
            else
            {
                formTwo .Reinitialaze(culture, invoice);
            }
            formTwo .BringToFront();
    }

}

public void SelectRow(int moveTo)
{
    try
    {
      /*navigate on list here */
  /* ... */

OpenSecondForm();
    }
    catch (Exception e)
    { MessageBox.Show(e.Message, "ERROR"); }
}

第二种形式:

public FormTwo(Form parent, CultureInfo cultr, string params)
{
    culture = cultr;

    parentForm = parent;
    rm = new ResourceManager("MyProject.Resource", typeof(FormOne).Assembly);
    InitializeComponent();

    xslTransform = new XslCompiledTransform();
    xslTransform.Load(XSL_TRANSFORM_SCHEMA_NAME);

    ReInitialazeAll();

}

internal void Reinitialaze(CultureInfo cultr, string params)
{
    culture = cultr;

    ReInitialazeAll();
}

private void ReInitialazeAll()
{
    SelectDatabaseData();

    InitCaptions();
    InitForms();

}

private void InitForms()
{
    EnableDisableButtons();
    webBrowser1.DocumentText = "<HTML><BODY></BODY></HTML>";

    FillXmlData();
}

private void FillXmlData()
{
    xslTransform.Transform(fi.FullName, TMP_TRANSFORMED_XML_PATH);
    webBrowser1.Navigate(TMP_TRANSFORMED_XML_PATH);
}

我尝试创建一个线程来执行这些 FillXmlData.但是我的表单在 xml 转换时仍然无法访问.

I've tried to create a thread to execute these FillXmlData. But my forms is still not accessible while xml is transforming.

推荐答案

您需要在单独的线程上运行 XML 转换(以及任何其他冗长的非 UI 加载操作).像这样:

You need to run the XML transformation (and any other lengthy non-UI loading operations) on a separate thread. Something like this:

public FormTwo(Form parent, CultureInfo cultr, string params)
{
    culture = cultr;

    parentForm = parent;
    rm = new ResourceManager("MyProject.Resource", typeof(FormOne).Assembly);

    InitializeComponent();

    // Show the progress bar
    this.ProgressBar.Visible = true;

    // Load on another thread
    Thread loadingThread = new Thread(new ThreadStart(TransformXml));
    loadingThread.Start();
}

private void TransformXml()
{
    xslTransform = new XslCompiledTransform();
    xslTransform.Load(XSL_TRANSFORM_SCHEMA_NAME);

    ReInitialazeAll();
}

注意:这里假设您的进度条名为 ProgressBar.

Note: This assumes your progress bar is named ProgressBar.

但是,您需要注意您无法访问另一个线程上的 UI 元素,因此需要在 UI 线程上调用对 ReInitialazeAll()(其中包含一个错字)的调用.这可以通过执行以下操作安全地完成:

However, you need to be aware that you cannot access UI elements on another thread, so the call to ReInitialazeAll() (which contains a typo) needs to be invoked on the UI thread. This can be accomplished safely by doing something like:

private void ReInitialazeAll()
{
    // Make sure we're running on the UI thread
    if (this.InvokeRequired)
    {
        BeginInvoke(new Action(ReInitialazeAll));

        return;
    }

    // Hide the progress bar
    this.ProgressBar.Visible = false;

    // ... execute UI-related code
}

这应该会给你一个足够好的开始,你可以从中工作.

This should give you a decent enough start that you can work from.

这篇关于线程,进度条操作方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆