Thursday, June 27, 2013

Adding descriptive attribute to Enumerations in C#

Enumerations allows to add constants to be declare in the group. Main idea behind the enums are to make code more readable and maintainable. However these enum names are not suitable for display to the end user. This is most obvious when working with constants that combine two or more words, as no spaces, punctuation or other special characters are permitted.

Ex: enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri},
      enum Mode {Create, Delete, Modify}


If we can add description to each enum value then we can display the particular description instead of enum value. This article will focus on adding descriptive attribute to enum using extension method.



Step 1:
Create sample enum like below which is use to store form name categories and add following directive 

using System.ComponentModel;
(To add the descriptive attribute for each enum we should use above directive)

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

namespace EnumExample
{
    public enum FormCategory
    {
        RegistrationForm,
        DisplayClient,
        DeleteClient,       
        EditClient,
        AddNewClient,
    }
}






Step 2 :
Then add the descriptive attribute to each enum which is going to display to end user.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace EnumExample
{
    public enum FormCategory
    {
        [Description("Client Registration Form")]
        RegistrationForm,

        [Description("Display Client Information Form")]
        DisplayClient,

        [Description("Delete Client Form")]
        DeleteClient,

        [Description("Edit Existing Client Form")]
        EditClient,

        [Description("Add New Client Form")]
        AddNewClient,
    }
}




Step 3 :
Mechanism behind displaying enum description instead of enum value is .Net Reflection. The extension method will use reflection to examine the values in any enumeration and look for the Description attribute. Where present, the description will be returned. If the description is absent, the constant name will be returned instead.

Create static  class called EnumExampleExtensions.cs and add following directives,
using System.Reflection;
using System.ComponentModel;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace EnumExample
{
    public static class EnumExampleExtensions
    {
    }
}





Step 4:
Create static extension method Description which takes enum as parameter  like below.

public static string Description(this Enum enumValue)
{
            var enumType = enumValue.GetType();
            var field = enumType.GetField(enumValue.ToString());
            var attributes = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
            return attributes.Length == 0
                ? enumValue.ToString()
                : ((DescriptionAttribute)attributes[0]).Description;
}

In above code take the enum value and then resolve its description. GetField method is called, passing the name of the enumeration value provided in the method's parameter. This obtains the field information for the value. Finally check the description attribute and if attribute contains description return the description if not return the enum constant name.

Step 5:
Now it's time to test the code. I'm using console application for test the code.

Code :
Console.WriteLine(string.Format("Enum Value{0}", 
FormCategory.RegistrationForm.ToString()));

Console.WriteLine( 
string.Format("Enum Description{0}", 
FormCategory.RegistrationForm.Description()));
Console.ReadKey();

Output:



Saturday, December 29, 2012

CPU Usage Monitoring Tool


This tool displays CPU usage of each core of the computer separately. You can change settings by double click on the tool area.



.Net Framework 4.0 Required.
Download Link

Saturday, December 8, 2012

Allowing Only One Instance of an Application in Windows Forms C#

Standard Windows Forms applications can be launched multiple times and each instance used completely independently of the others. However, sometimes it is important to restrict the user in launching a single instance of a program.

The Process Class
The System.Diagnostics namespace contains a class namedProcess. This class contains functionality that allows interrogation of the processes that are currently executing in Microsoft Windows. The class can be used to determine if any other instances of an application are running and, if one is, a decision can be made to stop the current program.

Detecting Other Instances
To determine if another instance of a program is executing, twostatic methods of the Process class are used. Firstly, a call to the GetCurrentProcess method is made. This returns the current program's process details including its name within the returned object's ProcessName property.
Once the process name is known, the GetProcessesByName method can be used to return an array of Process objects with one representing each instance of the named software. This list includes the current program so if there is more than one element in the array there must be other running instances of the software.

Adding Detection to an Application
Using the two methods described, a simple test can be made within the Main method of an application. The following C# code demonstrates this by checking the number of matching processes and showing an error message if another instance is active. The method is then simply returned from to close the application. This is done before the main form of the application is loaded.

CODE :
static void Main()
{
     // Detect existing instances
     string processName = Process.GetCurrentProcess().ProcessName;      
     Process[] instances = Process.GetProcessesByName(processName);
    if (instances.Length > 1)
    {
             MessageBox.Show("This application is already running.");
             return;
     }
    // End of detection Application.EnableVisualStyles();                
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}