Theme, progress

I am using XslCompiledTransform to convert an XML file to HTML. The XML file is not so short, so the conversion is very time-consuming.

My code is:

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

So, I want to use a progress indicator or (best) progress (dialogue?) That is not tied to form.

The problem is that I have two forms. The first one has a list of elements and a button, when the item is selected and the button is pressed, the 2nd form (not modal) is displayed, the XML file conversion is displayed and it is displayed in the WebBrowser control.

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

In the second form, I also have buttons for moving between list items of the 1st form. Therefore, when I click '>', the next element from the 1st form is selected, and the elements of the second form are reloaded - for example, some text has been changed, and XslCompiledTransform.Transform () is again called for the new XML file.

So how to organize a progress bar while the second form loads every time?

From the 1st form:

 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"); } } 

Second form:

 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); } 

I tried to create a thread to execute these FillXmlData. But my forms are still not available while xml is being transformed.

+1
source share
1 answer

You need to run the XML conversion (and any other lengthy download operations without a UI) in a separate thread. Something like that:

 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(); } 

Note. It is assumed that your ProgressBar bar is called a ProgressBar .

However, you need to know that you cannot access the user interface elements in another thread, so a call to ReInitialazeAll() (which contains a typo) must be called in the user interface thread. This can be done 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 pretty decent start from which you can work.

+1
source

Source: https://habr.com/ru/post/902928/


All Articles