Single Instance of Child Forms in MDI Applications

22. February 2010 00:40

C# 

In MDI application we can have multiple forms and can work with multiple forms i.e. MDI childs at a time but while developing applications we don't pay attention to the minute details of memory management. Take this as an example, when we develop application say preferably an MDI application, we have multiple child forms inside one parent form. On MDI parent form we would like to have menu strip and tab strip which in turn calls other forms which build the other parts of the application. This also makes our application looks pretty and eye-catching (not much actually). Now on a first go when a user clicks a menu item or a button on a tab strip an application initialize a new instance of a form and shows it to the user inside the MDI parent, if a user again clicks the same button the application creates another new instance for the form and presents it to the user, this will result in the un-necessary usage of the memory. Therefore, if you wish to have your application to prevent generating new instances of the forms then use the below method which will first check if the the form is visible among the list of all the child forms and then compare their types, if the form types matches with the form we are trying to initialize then the form will get activated or we can say it will be bring to front else it will be initialize and set visible to the user in the MDI parent window. The method we are using:

private bool CheckForDuplicateForm(Form newForm)
{
     bool bValue = false;
     foreach (Form frm in this.MdiChildren)
     {
         if (frm.GetType() == newForm.GetType())
         {
             frm.Activate();
             bValue = true;
         }
      }
      return bValue;
}

Usage: First we need to initialize the form using the NEW keyword

ReportForm ReportForm = new ReportForm();

We can now check if there is another form present in the MDI parent. Here, we will use the above method to check the presence of the form and set the result in a bool variable as our function return bool value.

bool frmPresent = CheckForDuplicateForm(Reportfrm);

Once the above check is done then depending on the value received from the method we can set our form.

if (frmPresent)
	return;
else if (!frmPresent)
{
    Reportfrm.MdiParent = this;
    Reportfrm.Show();
}

In the end this is the code you will have at you menu item or tab strip click:

ReportForm Reportfrm = new ReportForm();
bool frmPresent = CheckForDuplicateForm(Reportfrm);
if (frmPresent)
return;
else if (!frmPresent)
{
    Reportfrm.MdiParent = this;
    Reportfrm.Show();
}
Currently rated 3.5 by 4 people

How to plug-in a DLL into a C# project

7. January 2010 16:58

.NET Framework C# 

John Grove share a code at MSDN on how can we call DLLs methods dynamically using C# code.

The below code can further be modified and a developer can easily extend the functionality of his application to create a application which accepts DLLs as plug-ins. This concept is useful when different users have different requirements in a generalized application like in the case of famous photo editing program Photoshop from Adobe. Here anyone can create a plug-in and hook it up with the host application which further inherits all the functionalities from the DLL.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly assembly = Assembly.LoadFrom(@"C:\Documents and Settings\john.grove\MyMath.dll");
            Type mathUtility = assembly.GetType("MyMathUtilty");
            Object theInstance = Activator.CreateInstance(mathUtility);
            Int32 result = (Int32)mathUtility.InvokeMember("Add", BindingFlags.InvokeMethod, null, theInstance, new object[] { 56, 26 });
            Console.WriteLine("Dynamically invoking MyMathUtilty Add method");
            Console.WriteLine("56 + 26 = {0}", result);
            Console.WriteLine("");

            // get all public static methods of MyMathUtilty type
            MethodInfo[] methodInfos = mathUtility.GetMethods(BindingFlags.Public | BindingFlags.Static);
            Console.WriteLine("All public/static methods in MyMathUtilty");
            Console.WriteLine("----------------------------------------");
            for (Int32 i = 0; i < methodInfos.Count(); i++ )
                Console.WriteLine("{0}.) {1}", i + 1, methodInfos[i].Name);
            Console.ReadLine();
        }
    }
}
Currently rated 4.0 by 2 people

Removing Duplicates from a List in C#

24. December 2009 18:25

.NET Framework C# Code Snippets 

For more details and detailed explaination of the code visit this link.

static List removeDuplicates(List inputList)
        {

            Dictionary uniqueStore = new Dictionary();
            List finalList = new List();
	    foreach (string currValue in inputList)
            {

                if (!uniqueStore.ContainsKey(currValue))
                {

                    uniqueStore.Add(currValue, 0);
                    finalList.Add(currValue);

                }

            }
            return finalList;
         }
 No Rating

Retrieve Key from Value in Hash Table

16. December 2009 02:10

C# Code Snippets 

Working with hash tables is pretty simple but few days back I was having a problem in retrieving a key from a value in hash table. I was bit lazy to find a way myself, so I searched the net and here is what I got....a simple piece of code which lead to me to complete my task and so I thought I should share it with everyone here.

public string FindKey(string Value, Hashtable HT)
{
       string Key = "";
       IDictionaryEnumerator e = HT.GetEnumerator();
       while (e.MoveNext())
       {
            if (e.Value.ToString().Equals(Value))
            {
               Key = e.Key.ToString();
            }
       }
       return Key;
}
Currently rated 4.2 by 11 people

Using Background Worker in C#

27. November 2009 15:42

.NET Framework C# 

Performance of an application matters a lot for a developer. None of the developer wants his application freezes or crashes. But what are measures a developer should takes to keep it all good going. When I used to develop application I saw whenever I try to perform some heavy or bulky task like uploading files, copying files from place to other and other DB related but heavy task which includes CPU as well as hard drive.

Most of our application that we develop today require simultaneous functions to perform but with performance. We guarantee our client…yes the application can handle all the functions but on the stake of performance. The major fallback of any application is limiting a user to perform one task at a time. So how do we deal with application freezing and crashing?

Working with Microsoft .NET framework we have worked with threads through which we can handle all the tasks simultaneously under one main application thread. You can perform smaller operations with the help of Threading class, instead I prefer using Background Worker class to implement to perform all my heavy duty operations.
Background worker class is introduced in .NET framework 2.0 and using this class makes it easy to execute long running operations on a separate thread, support cancellation, progress reporting and marshalling results back to the UI thread.

Below image which provides an overview of background worker class which found here.

 

Now we will see how to use background worker class to perform heavy operations.

First create a new windows application as shown below.

 

Get to the design mode and drag & drop the background worker component.

Set the properties of the background worker:

Set GenerateMember and Modifiers as it is. In the sample application we have a progress bar which reports the percentage of the task completed so we need to set the WorkerReportsProgress to true and similarly if we want the user to cancel the running operation then set the WorkerSupportsCancellation to true.

Now the next step is to create 3 methods:

1.) DoWork: This is the main method which is responsible to handle the large operation. The code here is not different than the usual code.
2.) ProgressChanged: This method reports the change in the progress of the operation performed by the background worker DoWork method.
3.) RunWorkerCompleted: This method checks the RunWorkerCompletedEventArgs and perform action accordingly.

So how do we code these methods? It’s easy and not a complex task as it sounds, so let’s have a look at these methods….

To carry on with this example, I am using an AventureWorks database I have query the table Person.Contact as it has a large number of records, around 19K. Now here, to set the progress bar you first need to set the maximum property of the progress bar so we can show the progress completed.

Starting with the Start button:

private void btn_start_Click(object sender, EventArgs e)
{
//Starts the backgroundworker process asynchronously
bgw.RunWorkerAsync(); 
btn_start.Enabled = false;
}

The DoWork method:

//Background worker DoWork method. Here we will perform our heavy duty tasks.
//I have used a simple datareader object to traverse all the rows in the table. 
//The table has around 19K rows.
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
  try
  {
	int i = 0;
	cmd = new SqlCommand("SELECT * FROM Person.Contact", con);
	con.Open();
	dr = cmd.ExecuteReader();
	while(dr.Read())
	{
		i = i + 1;
		//report to the backgroungworker progreechanged event of the background worker class
		bgw.ReportProgress(i);
		Thread.Sleep(1);
		//Called and check if the cancellation of the operation is pending. If returned true
		//DoWorkEventArgs object cancels the operation.
		if (bgw.CancellationPending)
		{
			e.Cancel = true;
			return;
		}
	}
   }
   catch (Exception x)
   {
	MessageBox.Show("An error occured while performing operation" + x);
   }
   finally
   {
	con.Close();
   }
}

The RunWorkerCompleted Method:

private void bgw_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
{
	if (e.Cancelled)
	{
		MessageBox.Show("Operation Cancelled");
		btn_start.Enabled = true;
	}
	else
	{
		MessageBox.Show("Operation Completed");
		btn_start.Enabled = true;
	}
}

The ProgressChanged Method:

private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
	//Report porogress bar change
	progress.Value = e.ProgressPercentage;
}

Ending up with the cancel button:

//To cancel async operation
private void btn_cancel_Click(object sender, EventArgs e)
{
	 //To cancel the asynchronous operation
	 bgw.CancelAsync();
	 progress.Value = 0;
	 btn_start.Enabled = true;
}

So when your application is traversing the records and suddenly you think that you should quit the job and work on other part of the application, just hit the cancel button and the large operation will get cancelled withoud any freezing and hanging of your application.

Download: BackgroundWorkerDemo.zip (43.69 kb)

Currently rated 4.8 by 17 people