Udostępnij za pośrednictwem


Adding an InfoPath Preloader (ProgressBar) for long loading forms

Working on a project with some very large InfoPath forms (700+ fields with hundreds of rules and conditions etc.) running out of a SharePoint Forms library using the InfoPath client (not Forms Server) and which take over a minute to load.

In addition to a number of changes made to reduce the load time discussed elsewhere, it was decided to improve the user experience by adding a Pre-Loader to give the user some feedback while the form is loading.

Here is how this was done in C# (feedback appreciated - particularly if you know of a better way to do this):

     0. Add a reference to System.Drawing and then add the following using statements at the top of the FormCode.cs file (there may be others):

            using System.Drawing;

            using System.Diagnostics;

            using System.Threading;

 

 

  1.  Add the following using statement at the top of the FormCode.Designer.cs (click on "Show All Files" if you don't see this file under the FormCode.cs file)

              using System.Windows.Forms

 

          Declare the preLoaderForm at the top of FormCode.Designer.cs* under the "internal Microsoft.Office.InfoPath.Application Application;" and "internal Microsoft.Office.InfoPath.EventManager EventManager;" declarations:

 

           internal Form preloaderForm = null;

  1. Add inside the FormCode constructor in the FormCode.Designer.cs*

LaunchPreLoader();

  1. Add two new methods to FormCode.cs

        private void LaunchPreLoader()

        {

            try

            {

                System.Threading.Thread newThread = new System.Threading.Thread(new System.Threading.ThreadStart(this.Preloader));

                newThread.Start();

            }

            catch

            {

                // do nothing

            }

        }

        private void Preloader()

        {

            try

            {

                preloaderForm = new Form();

                preloaderForm.Text = "Form Loading";

                preloaderForm.Size = new System.Drawing.Size(250, 75);

                preloaderForm.Location = new System.Drawing.Point(400, 200);

                preloaderForm.StartPosition = FormStartPosition.CenterScreen;

                Label message = new Label();

                message.Text = "Your form is loading";

                message.Location = new System.Drawing.Point(20, 8);

                message.Size = new System.Drawing.Size(200, 15);

                Panel progBarPanel = new Panel();

                progBarPanel.Width = 250;

                progBarPanel.Height = 50;

                progBarPanel.BackColor = Color.Gainsboro;

 

                ProgressBar progBar = new ProgressBar();

                progBar.Location = new System.Drawing.Point(20, 20);

                progBar.Style = ProgressBarStyle.Marquee;

                progBar.MarqueeAnimationSpeed = 250;

                progBar.BackColor = Color.DodgerBlue;

                progBar.Size = new System.Drawing.Size(200, 15);

                progBarPanel.Controls.Add(message);

                progBarPanel.Controls.Add(progBar);

                preloaderForm.Controls.Add(progBarPanel);

                preloaderForm.ShowDialog();

            }

            catch

            {

                // do nothing if preloader fails

            }

        }

  1. To close the pre-loader, add the following code to the bottom of the FormEvents_Loading method in FormCode.cs. If you don't see a FormEvents_Loading method in your FormCode.cs file, then in InfoPath go to Tools > Programming > Loading Event - and it will be generated for you.

If( preloaderForm != null )

            {

                        preloaderForm.DialogResult = DialogResult.Yes;

}

*Note that steps 1 and 2 are in the FormCode.Designer.cs file. It is not advisable to make changes to this file since it is autogenerated and your changes can be easily lost. But on the onther hand, the Pre-Loader is only useful if it opens early enough, and the FormCode constructor is the earliest point we can get to in the FormCode class. If you cannot deal with the maintenance issue when this code is autogenerated (re-adding the three lines of code in steps 1 and 2) then you can try locating this code in FormCode.cs and see if it runs early enough to be useful to you.

Comments

  • Anonymous
    July 17, 2008
    Wouldn't this result in the creation and display of a form on a thread other than the UI thread?  That is in violation of Windows guidelines (and would throw an exception in 2.0+ Framework).

  • Anonymous
    July 17, 2008
    The comment has been removed