George Shepherd's Windows Forms FAQ
Questions and answers in this FAQ have been collected from newsgroup posts, various mailing lists and the employees of Syncfusion.

14. Windows Forms Patterns

WinForms FAQ Home
   14.1 How to display a status dialog in a background thread during a long operation and allow the user to cancel?
   14.2 How can I throw my events asynchronously?
   14.3 Why are the Tooltips not being shown on a NumericUpDown control?
   14.4 How to get the hyperlink and the hyperlink text dragged from IE in my Control's drag-drop event?



14.1 How to display a status dialog in a background thread during a long operation and allow the user to cancel?


You can do this by starting a new thread and executing Application.Run for the status dialog form when the background thread starts running. To communicate changes in percentage use BeginInvoke to executes a specific delegate asynchronously on the thread that the form was created on.

Download the ProgressThread progressthread.zip sample for a complete implementation of a BackgroundThreadStatusDialog class that shows a status dialog in a separate thread.

In order to use BackgroundThreadStatusDialog from your code you have to update the Progress inside your loop and check the IsCanceled state to detect if the user pressed the Cancel button.


          private void button1_Click(object sender, System.EventArgs e)
          {
               BackgroundThreadStatusDialog statusDialog = new BackgroundThreadStatusDialog();
               try
               {
                    for (int n = 0; n < 1000; n++)
                    {
                         statusDialog.Percent = n/10;
                         int ticks = System.Environment.TickCount;
                         while (System.Environment.TickCount - ticks < 10)
                              ;
                         if (statusDialog.IsCanceled)
                              return;
                    }
                    statusDialog.Close();
                    MessageBox.Show(statusDialog.IsCanceled ? "Canceled" : "Success");
               }
               finally
               {
                    statusDialog.Close();
               }
          }



14.2 How can I throw my events asynchronously?


Your managed code dosent have a destructor, just a finalizer. The difference is a destructor (as in C++) fires immediately when an object goes out of scope, but a finalizer is run when the CLR's garbage collector (GC) gets to your object. It cannot be determined when this will occur, but it's very unlikely to occur right after the object goes out of scope. It will happen at a later time, however.

(from sburke_online@microsoft..nospam..com on microsoft.public.dotnet.framework.windowsforms)


14.3 Why are the Tooltips not being shown on a NumericUpDown control?


This is because of a bug in the .net framework. When tooltips are set on a control that hosts other controls within it (like the numeric updown), tooltips are not shown on those child controls. To workaround this issue, do the following in code:


[C#]
foreach(Control c in this.numericUpDown1.Controls)
{
     this.tooltip.SetToolTip(c, "mytooltip");
}



[VB.Net]
Dim c As Control
For Each c In Me.numericUpDown1.Controls
     Me.tooltip.SetToolTip(c, "mytooltip")
Next



14.4 How to get the hyperlink and the hyperlink text dragged from IE in my Control's drag-drop event?


Compiled from the newsgroup posts by Andy Fish and Brian:

You can do this in the DragDrop event handler of your control:


[C#]
try
{
     //Use e.Data.GetData("UniformResourceLocator") to get the URL
     System.IO.Stream ioStream=
     (System.IO.Stream)e.Data.GetData("FileGroupDescriptor");
     byte[] contents = new Byte[512];
     ioStream.Read(contents,0,512);
     ioStream.Close();
     StringBuilder sb = new StringBuilder();
     //The magic number 76 is the size of that part of the
     //FILEGROUPDESCRIPTOR structure before the filename starts - cribbed
     //from another usenet post.
     for (int i=76; contents[i] != 0; i++)
     {
          sb.Append((char)contents[i]);
     }
     if (!sb.ToString(sb.Length-4,4).Equals(".url"))
     {
          throw new Exception("filename does not end in '.url'");
     }
     filename = sb.ToString(0,sb.Length-4);

}
catch(Exception ex)
{
     MessageBox.Show(ex.ToString());
}



[VB.Net]
Try
     'Use e.Data.GetData("UniformResourceLocator") to get the URL
     System.IO.Stream ioStream=
     CType(e.Data.GetData("FileGroupDescriptor"), System.IO.Stream)
     Dim contents() As Byte = New Byte(512) {}
     ioStream.Read(contents,0,512)
     ioStream.Close()
     Dim sb As StringBuilder = New StringBuilder()
     
     'The magic number 76 is the size of that part of the
     'FILEGROUPDESCRIPTOR structure before the filename starts - cribbed
     'from another usenet post.
     Dim i As Integer
     For i = 76 To contents(i) 0 Step i + 1
          sb.Append(CType(contents(i), Char))
     Next
     If Not sb.ToString(sb.Length-4,4).Equals(".url") Then
          Throw New Exception("filename does not end in '.url'")
     End If
     filename = sb.ToString(0,sb.Length-4)
Catch ex As Exception
     MessageBox.Show(ex.ToString())
End Try


© 2001-2010 Copyright Syncfusion Inc. All rights reserved.  |  Privacy Policy  |  Contact  |  Sitemap