Skip to main content

Continue executing code after calling ShowDialog() using C#

In  C# windows form application using ShowDialog() a user can show a form as modal dialog. Here we cannot access the rest application or continue execution of the code until the modal dialog is closed.

Sometimes we need to show modal dialog to user and we need to perform some background operations with parent form control without closing the dialog box. For example - we are doing some calculation and on the basis of these calculation we are moving the progress bar control on dialog box. Here is the c# code by which user can continue executing code after showing modal dialog using ShowDialog() -


ReaderWriterLockSlim ScanLock = new ReaderWriterLockSlim();
 private void Form1_Load(object sender, EventArgs e)
        {
            ScanLock.EnterWriteLock();
           
           UIThread(()=>
            {
               WindowsFormsSynchronizationContext.Current.Post(_ =>
               {
                   Form2 frm = new Form2();
                   frm.ShowDialog();
               }, null);
             });
            

            //Do you work here
            //update UI part
            UIThread(()=>
            {
               label1.Text = "Hello World";
            });
        }

By executing the modal dialog code inside Post methods of WindowsFormsSynchroizationContext class we can continue to execute code without closing the modal dialog. In the above code after frm.ShowDialog() execution "label1.Text = "Hello World";" will be executed without closing the modal dialog

Another method to display progress on UI while executing business logic in background is by using events. Let's suppose a scenario where we have business logic written in a separate DLL and while executing code from DLL we want to show progress on UI. To do this we can create a custom event. From DLL pass a custom event argument having information related to current progress and envoke the event. In UI code handle the event and update UI as per the argument information sent from the DLL code.

Here is a sample code:

//DLL code
//delegate
public delegate void delUpdateProgress(object sender, stSendProgress oSendProgress);

 public class TestLibraryClass
{
 //event
 public event delUpdateProgress evtUpdateProgress;
 public void TestFunction()
 {
  for(int i = 0; i < 100; i++)
  {
   // do your work here
   stSendProgress oSendProgress = new stSendProgress();
   oSendProgress.CountFileScanned = i;
   evtUpdateProgress(this, oSendProgress); //send progress
  }
 }
}

    [Serializable]
    public class stSendProgress 
    {
        /// <summary>
        /// number of files scanned
        /// </summary>
        public int CountFileScanned;
    }


//Code in Main Application
TestLibraryClass.evtUpdateProgress += new delUpdateProgress (test_evtUpdateProgress);
void evtUpdateProgress(object sender, stSendProgress oProgress)
{
 //update progress
}

Comments

  1. Thanks ...it's nice and useful....

    ReplyDelete
  2. Thanks ...it's nice and useful....

    ReplyDelete
  3. Thanks, It is a very useful article.

    Can you let us know more on what is UIThread?

    ReplyDelete
    Replies
    1. UIThread is a function to execute any action (or code) asynchronously without blocking execution of calling thread. In UIThread function code is passed as delegate and using invoke method of .net framework the passed delegate is executed on the thread that owns the control's underlying window handle.

      Delete

Post a Comment

Popular posts from this blog

Show Image on canvas HTML5

Here is the sample code to select image from system and display it on html5 canvas and javascript: <input type= "file" id= "selectedImage" /> <canvas id= "myCanvas" width= "500" height= "500" > </canvas> Javascript code: $( "#selectedImage" ).change( function (e) { var URL = window .URL; var url = URL.createObjectURL(e.target.files[ 0 ]); img.src = url; img.onload = function () { var canvas = document .getElementById( "myCanvas" ); var ctx = canvas.getContext( "2d" ); var imgSize = calculateAspectRatioFit(img.width, img.height, canvas.clientWidth, canvas.clientHeight); ctx.clearRect( 0 , 0 , canvas.width, canvas.height); ctx.drawImage(img, 0 , 0 , imgSize.width, imgSize.height); } }); function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) { var ratio = Math .min(maxWi

Pass byte array from C# to C++ and vice-versa

Pass byte array from C# to C++                           If you want to pass a byte array to native DLL as parameter, you can use the Intptr to do this, please check the demo below. /C++ API code: TestDLL_API void TestArrayPara (BYTE * pArray, int nSize) { for ( int i= 0 ; i<nSize; i++) printf( "%d\n" , pArray[i]); } //C# code: class TestClass { [DllImport(@"TestDll.dll")] public static extern void TestArrayPara (IntPtr pArray, int nSize); public static void Test () { byte [] array = new byte [ 16 ]; for ( int i = 0 ; i < 16 ; i++) { array[i] = ( byte )(i + 97 ); } int size = Marshal.SizeOf(array[ 0 ]) * array.Length; IntPtr pnt = Marshal.AllocHGlobal(size); try { // Copy the array to unmanaged memory. Marshal.Copy(array, 0 , pnt, array

Display Tooltip for Combo Box item C#.NET Winforms

In windows form combo box control sometimes while adidng items dynamically we have items whose width is greater than width of combox box control. In this case for making UI more user friendly we can show tooltip over such item. Here is the sample C# code to display such tooltip:  Add a Tooltip control on the form.  Add following code : this . combo_box1 . DropDownStyle = System . Windows . Forms . ComboBoxStyle . DropDownList; this . combo_box1 . DrawMode = DrawMode . OwnerDrawFixed; this . combo_box1 . DrawItem += new DrawItemEventHandler(combo_box1_DrawItem); this . combo_box1 . DropDownClosed += new EventHandler(combo_box1_DropDownClosed); this . combo_box1 . MouseLeave += new EventHandler(combo_box1_Leave); void combo_box1_DrawItem( object sender, DrawItemEventArgs e) { if (e . Index < 0 ) { return ; } string text = combo_box1 . GetItemText(combo_box1 . Items[e . Index