Example #1
0
        ///<summary>FormProgressExtended is extremely tailored to monitoring the progress of FormBilling.
        ///Much will need to change about this to make it generic.
        ///Launches a progress window that will listen specifically for ODEvents with the passed in name.
        ///Returns an action that should be invoked whenever the long computations have finished which will close the progress window.
        ///eventName should be set to the name of the ODEvents that this specific progress window should be processing.
        ///eventType must be a Type that contains an event called "Fired" and a method called "Fire".
        ///Optionally set tag to an object that should be sent as the first "event arg" to the new progress window.
        ///	This will typically be a ProgressBarHelper.</summary>
        ///<param name="currentForm">The form to activate once the progress is done. If you cannot possibly pass in a form, it is okay to pass in null.
        ///</param>
        public static Action ShowProgressExtended(string eventName, Type eventType, Form currentForm, object tag = null,
                                                  ProgressCanceledHandler progCanceled = null, ProgressPausedHandler progPaused = null, EventHandler formShown = null)
        {
            bool     isFormClosed = false;
            ODThread odThread     = new ODThread(new ODThread.WorkerDelegate((ODThread o) => {
                FormProgressExtended FormPE = new FormProgressExtended(eventName, eventType);
                FormPE.FormClosed          += new FormClosedEventHandler((obj, e) => {
                    isFormClosed = true;
                });
                if (progCanceled != null)
                {
                    FormPE.ProgressCanceled += progCanceled;
                }
                if (progPaused != null)
                {
                    FormPE.ProgressPaused += progPaused;
                }
                if (formShown != null)
                {
                    FormPE.Shown += formShown;
                }
                //FormProgressExtended should NOT be the top most form.  Other windows might be popping up requiring attention from the user.
                //FormPE.TopMost=true;//Make this window show on top of ALL other windows.
                if (tag != null)
                {
                    FormPE.ODEvent_Fired(new ODEventArgs(eventName, tag));
                }
                //Check to make sure that the calling method hasn't already finished its long computations.
                //odThread's tag will be set to "true" if all computations have already finished and thus we do not need to show any progress window.
                if (o.Tag != null && o.Tag.GetType() == typeof(bool) && (bool)o.Tag)
                {
                    try {
                        FormPE.Close();                        //Causes FormProgressStatus_FormClosing to get called which deregisters the ODEvent handler it currently has.
                    }
                    catch (Exception ex) {
                        ex.DoNothing();
                    }
                    return;
                }
                FormPE.BringToFront();
                //From this point forward, the only way to kill FormProgressStatus is with a DEFCON 1 message via an ODEvent with the corresponding eventName.
                FormPE.ShowDialog();
            }));

            odThread.SetApartmentState(ApartmentState.STA);                                     //This is required for ReportComplex due to the history UI elements.
            odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { })); //Do nothing.
            odThread.Name = "ProgressStatusThread_" + eventName;
            odThread.Start(true);
            return(new Action(() => {
                //For progress threads, there is a race condition where the DEFCON 1 event will not get processed.
                //This is due to the fact that it took the thread longer to instantiate FormProgressStatus than it took the calling method to invoke this action.
                //Since we don't have access to FormProgressStatus within the thread from here, we simply flag odThread's Tag so that it knows to die.
                if (odThread != null)
                {
                    odThread.Tag = true;
                }
                //Send the phrase that closes the window in case it is processing events.
                eventType.GetMethod("Fire").Invoke(eventType, new object[] { new ODEventArgs(eventName, "DEFCON 1") });
                if (currentForm != null)
                {
                    //When the form closed on the other thread it was sometimes causing the application to go behind other applications. Calling Activate()
                    //brings the application back to the front or causes it to flash in the taskbar.
                    DateTime start = DateTime.Now;
                    while (!isFormClosed && (DateTime.Now - start).TotalSeconds < 1)                   //Wait till the form is closed or for one second
                    {
                        Thread.Sleep(1);
                    }
                    if (!currentForm.IsDisposed)
                    {
                        currentForm.Activate();
                    }
                }
            }));
        }
Example #2
0
        ///<summary>Non-blocking call. FormProgressExtended is an extremely tailored version of FormProgressStatus.
        ///It is a progress window that can have multiple progress bars showing at the same time with pause and cancel functionality.
        ///This "extended" progress window is exactly like the "Show()" progress window in that the close action that is returned must be invoked
        ///by the calling method in order to programmatically close.</summary>
        ///<param name="odEventType">Causes the progress window to only process ODEvents of this ODEventType.  Undefined will process all types.</param>
        ///<param name="eventType">Causes the progress window to only process ODEvents of this Type.  Null defaults to typeof(ODEvent).</param>
        ///<param name="currentForm">The form to activate once the progress is done. If you cannot possibly pass in a form, it is okay to pass in null.</param>
        ///<param name="tag">Optionally set tag to an object that should be sent as the first "event arg" to the new progress window.
        ///This will typically be a ProgressBarHelper or a string.</param>
        ///<param name="progCanceled">Optionally pass in a delegate that will get invoked when the user clicks Cancel.</param>
        ///<param name="progPaused">Optionally pass in a delegate that will get invoked when the user clicks Pause.</param>
        ///<returns>An action that will close the progress window.  Invoke this action whenever long computations are finished.</returns>
        public static Action ShowExtended(ODEventType odEventType, Type eventType, Form currentForm, object tag = null,
                                          ProgressCanceledHandler progCanceled = null, ProgressPausedHandler progPaused = null, string cancelButtonText = null)
        {
            Action actionCloseProgressWindow = ShowProgressBase(
                () => {
                FormProgressExtended FormPE = new FormProgressExtended(odEventType, eventType, cancelButtonText: cancelButtonText);
                if (progCanceled != null)
                {
                    FormPE.ProgressCanceled += progCanceled;
                }
                if (progPaused != null)
                {
                    FormPE.ProgressPaused += progPaused;
                }
                //FormProgressExtended should NOT be the top most form.  Other windows might be popping up requiring attention from the user.
                //FormPE.TopMost=true;//Make this window show on top of ALL other windows.
                if (tag != null)
                {
                    FormPE.ODEvent_Fired(new ODEventArgs(odEventType, tag));
                }
                return(FormPE);
            }, "Thread_ODProgress_ShowExtended_" + DateTime.Now.Ticks);

            return(() => {
                actionCloseProgressWindow();                //Make sure the progress window is closed first.
                //If a form was passed in, activate it so that it blinks or gets focus.
                if (currentForm != null && !currentForm.IsDisposed)
                {
                    currentForm.Activate();
                }
            });
        }