Bubbling up Events Example in WinForm C#


Suppose you have a Windows Forms application in which you want to see the intermediate progress and status of a time-consuming process in the GUI of the Main Form. This time-consuming process is running in a separate DLL. As the process progresses, the DLL sends current status/progress to the calling application (the Windows Forms application).

In the GUI of the Calling application, the progress and current status text of the process is displayed in a Progress Bar as shown below:

event1.gif

Let us see how we can do this in a very simple way:

  • Create a Main Application (Windows Forms application) as above with a "Start Process" button that starts the process in the DLL. Add a "StatusStrip" control too in the form. In the StatusStrip, add a ProgressBar (builtin) and StatusLable controls (builtin)
  • Create a DLL (Class Library project) with a class named "MyClass". Add the reference of this DLL into your Main Application.
  • Now create a public delegate to raise the Status event to show the intermediate processing status on the GUI in the Main Form as:

    public delegate void MyDLL_InternalStatus(int progress, string statustext);

    In this delegate, we are specifying the parameters:
    • the progress variable is used for storing the current percentage progress of the process.
    • A Statustext variable is used for storing the current status message related to the process.
       
  • In the "MyClass" class, add a method TimeConsumingProcess() that simulates a process taking a lot of time. TimeConsumingProcess() is built up with smaller several tasks such as Task-1, task-2 etc. Assume each task requires a significant amount of time (to simulate the time consumption, I used the Thread.Sleep() method)
    Now we want to send a current status to the calling application. In order to do this, we call MyClassStatusEvent() after the ending of each task.

    e.g. MyClassStatusEvent(10, "Task-1 is started. Task-1 is in process...");
     
  • Now add a reference to your DLL into your Main Application project. Then create an object of the "MyClass" and subscribe to its event as:

    // MyClass object is created
    oMyClass = new MyClassLibrary.MyClass();
     
    // MyClass's event is subscribed here
    oMyClass.MyClassStatusEvent +=
    new MyClassLibrary.MyDLL_InternalStatus (oMyClass_MyClassStatusEvent);

    This subscription will require an event handler, which we specify like this:

    // Event Handler of MyClass's event
    void oMyClass_MyClassStatusEvent(int progress, string statustext)
    {
           toolStripProgressBar.Value = progress;       
    // Setting ProgreeBar Value
           toolStripStatusLabel.Text = statustext;       // Setting Status Text  
         
    // To refresh the GUI simultaneously as the background process progresses
          Application.DoEvents();                      
    }

So, the whole code of the class "MyClass" looks like:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace MyClassLibrary
{
   
// Created a public delegate in the same namespace but outside of the class "MyClass"
    // in order to raise the Status event to show the intermediate processing status on
    // GUI in the Main Form
    public delegate void MyDLL_InternalStatus(int progress, string statustext); 
    public class
MyClass
    {
       
// Created a public event
        public event MyDLL_InternalStatus MyClassStatusEvent; 
        public void TimeConsumingProcess()
        {
           
// event firing
            MyClassStatusEvent(10, "Task-1 is started. Task-1 is in process...");            
            Task1();
            MyClassStatusEvent(20, "Task-1 is finished. Task-2 is in process...");            
            Task2();
            MyClassStatusEvent(40, "Task-2 is finished. Task-3 is in process...");            
            Task3();
            MyClassStatusEvent(60, "Task-3 is finished. Task-4 is in process...");            
            Task4();
            MyClassStatusEvent(80, "Task-4 is finished. Task-5 is in process...");            
            Task5();
            MyClassStatusEvent(100, "Task-5 is finished. All tasks completed sucessfully!");
        } 
       
// Suppose Task1 takes 2 seconds
        private void Task1()
        {
            Thread.Sleep(1000);
        } 
       
// Suppose Task2 takes 2 seconds
        private void Task2()
        {
            Thread.Sleep(2000);
        } 
       
// Suppose Task3 takes 4 seconds
        private void Task3()
        {
            Thread.Sleep(4000);
        }
 
       
// Suppose Task4 takes 3 seconds
        private void Task4()
        {
            Thread.Sleep(3000);
        }
 
        
// Suppose Task5 takes 2 seconds
        private void Task5()
        {
            Thread.Sleep(2000);
        }
    }
}

And the code of the calling application's main form ("MyForm") will look like:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms; 
namespace EventBubblerDemo
{
    public partial class MyForm :
Form
    {
       
// Created an object of the Dll
        MyClassLibrary.MyClass oMyClass; 
        public MyForm()
        {
            InitializeComponent();
 
           
// MyClass object is created
            oMyClass = new MyClassLibrary.MyClass();
 
           
// MyClass's event is subscribed here
            oMyClass.MyClassStatusEvent += new MyClassLibrary.MyDLL_InternalStatus(oMyClass_MyClassStatusEvent);
        }
 
       
// Event Handler of MyClass's event
        void oMyClass_MyClassStatusEvent(int progress, string statustext)
        {
            toolStripProgressBar.Value = progress;       
// Setting ProgreeBar Value
            toolStripStatusLabel.Text = statustext;       // Setting Status Text
 
           
// To refresh the GUI simultaneously as the background process progresses
            Application.DoEvents();                      
        } 
        ///
<summary>
        /// Start Button Click Method
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Start_Click(object sender, EventArgs e)
        {
            oMyClass.TimeConsumingProcess();
        }
    }
}

Thank You...