Monday, August 20, 2012

Reusable custom web control

When you are building web application, blog site, forum, shopping cart, etc, often, there are some information in "div" will be reuse throughout the website or reused in selected pages. To avoid writing the HTML tag again and again, you may consider using the custom web control.

To create custom web control, right click on your web project and choose Add New Item. Then, choose Web User Control (i.e., System.Web.UI.UserControl class). Web user control is able to utilize the HTML designer in Visual Studio. So, you will be able to complete the design in a shorter time.

Another way to create custom control is to writing codes by declaring a new control which inherits from CompositeControl or WebControl. But it does not support any visual designer. The biggest challenge is for the graphic designer to touch up the design in C#/VB.Net code because they are not the programmer.

Advantage of using UserControl:

  • Easily separate the JavaScript from the web page.
  • Easily moving the control around the web page.
  • Easier to test the custom web control.
  • Easier to share the same control in different design style with other projects.
  • Easier to maintain the design with or without using CSS file.
  • Reduce the complication of HTML tags within a page.

When to use it?

  • You have to display "modal dialogue" box in the page which requires JQuery dialog. This dialog requires a "div" for the dialog and also contains the many data entry fields.
  • The "compulsory" aster rick marker in red color.
  • The "last updates", "news" or "events" section.
  • The banner for header and footer.
  • Application menu.

Tuesday, August 14, 2012

Should I develop a custom control or just add it to the form

The definition of "reusable control":
  • The control will be reused in many areas in the same project - for example, "customer group" drop down list which can be reused in many screens within the same project.
  • The control will be used more than once in a project and also useful in other project - for example, DevExpress has developed xtraReport which can be reuse in many projects.
  • The control will be used only once in a project and also useful in other project - for example, you have developed a "main menu" control which reads the menu options from XML file.
In order to speed up the development, testing, implementation and maintenance, you are advisable to come out with a custom control and then drag it into other custom control or Form.

Tricks for using custom control:
  • Drag the custom control on a MDI child Form - in this case, you control will always sit inside the MDI parent window.
  • Drag the same custom control on a non-MDI child Form - in this case, you can shown the control modally.
  • Drag the same custom control into a Tab page control and show it in any Form - now, you custom control will be act like a tab page.
  • Another rare situation is that you instantiate this custom control at runtime and position it to the appropriate location. By doing this, you don't have to mess up the parent control/Form. The coding will be very clean and precise.

Tuesday, July 31, 2012

Designing reusable control Part 2 - designing composite control

Of course, when things are simple, you can always try to look for the best available control and create a child class from it. But, in real life, you won't always get the easiest job. This is the time that you need more than inheritance from the object oriented programming.. the composite control.

Steps to develop a composite control using UserControl
  1. Right click on the project.
  2. Choose Add new item.
  3. Select UserControl.
  4. Then, drag the necessary controls from the common control section into the UserControl that you have just added.
  5. Start writing some codes for this new UserControl. Of course, the most important will be loading data, validating user input and saving data. Another piece of code that is helpful is called "RefreshUI" which is responsible for controlling what should be hide or show on the screen base on the parent form/control. You might consider to add this method into your UserControl.
As simple as that, you have a composite control. Well, you can google for tutorial on the detailed steps with nice print screen. Sorry, I'm not going to repeat it. What I plan to do is to explain when do we need this?

From my experience, it seems many developers especially fresh graduate they "know" UserControl but "never use" it. Below is some example from live experience:
  • My customer asked me to develop an attendance grid which displays all the check-in guests. So, I started with "attendance item" control which displays the guest's photo + name. Then, I developed another control call "attendance grid". Finally, I developed "attendance" control which relies on both attendance item and attendance grid.
  • The situation gets complicated when you have domestic guests and international guests. These guests are using different "identity card" and the identity number are handled in different way. So, we develop a UserControl which is able to capture both domestic and international identity  number. This control is then reused in many of the screens.
  • We also develop a composite control to show the necessary options for the user for generating report.
  • Application menu is the composite control that will be reused in all projects.

Tuesday, July 24, 2012

Designing resuable control

Before we start the coding in any project, we have to identify the reusable screen, part of the screen or a group of fields. In this stage, we are developing custom control to be reuse in one or more projects.

Below is the reasons of developing custom control:

  • To reduce the overall development time - in Visual Studio, the custom control can be drag from the Toolbox and drop onto any WinForm or UserControl. Note: the custom control that you have added to the project will appear in the Toolbox after you have compiled the project or solution (if your custom control is residing in other project).
  • To reduce the testing time - this requires test once only because the control is reusable.
Below is the situation where you need to design a reusable control:
  • You are working on system that requires to capture "record status" which is used in many screens. 
  • The user might request for enhancement on this input control but the enhancement is not an urgent priority now
  • You are splitting the system into multiple small section to be handle by different programmer.
For example, in your system, there is a field that occur in many screens and it is called "status". It contains 4 statuses.In this case, you may add a new Class into the project and then set the base class (or parent class) to "ComboBox". It has a method name RefreshData which is responsible for loading the available statuses (which could be from database and it's up-to your design).
public class StatusComboBox : ComboBox
{
    public void RefreshData()
    {
        this.Items.Clear();
        this.Items.Add("Pending");
        this.Items.Add("In Progress");
        this.Items.Add("Completed");
        this.Items.Add("Cancelled");
    }
} 
After you have compiled the project, the StatusComboBox custom control will appear in the Toolbox. Below is the screen snapshot of the Toolbox:



Now, you may drag this control onto the Form and call "statusComboBox1.RefreshData()" to load the items.

Tuesday, July 10, 2012

Splitting the big piece into small pieces

Whenever you get a project, don't be so excited and start writing codes. Below is some guidelines that helps you in managing the project development. Please take note that this article is not covering the entire SDLC (system development life cycle).

Development flow:
  1. Ask for the sample reports and forms.
  2. Designing the database - add the standard table structures such as security module, session table, etc. Then, follow by the new table structures.
  3. Design the screen flow chart - you have to decide how many screens to the develop and the flow from one screen to another.
  4. Identify the reusable class that can be shared with other project.
  5. Identify the reusable custom control - most of the times, the screen (i.e., WinForm or WebForm can be splitted into multiple controls and then combine all the controls into one screen). This is very useful but requires thorough knowledge on the OOP (object oriented programming).
  6. Design the screen layout.
  7. Identify the shared functions - for example, the function to read the system settings out from the database or flat file.
  8. Designing the report layout - the user might pass you the hard copy of reports. But, sometimes you might have to propose new format (in digital format) that includes the chart/graph to show the summarize data.
  9. Start developing the system - now, you may start writing codes. I know you are waiting for this great moment.
  10. Fine tuning the screen flow - some users might not understand why you have to design the screen in this or that way. So, you might have to fine tune the screen to reduce the support calls and training time. This is a very important step where most of the projects might failed here.
  11. Fine tuning the field flow - this requires the feedback from the user where you might not have the full knowledge of the business.
  12. Fine tuning the menu options - some of the menu option can be remove and replace by shortcut button or popup menu.
  13. Add shortcuts or popup menu - I know this is not critical to any system but you should always do this. Most of the users will appreciate your effort in this area and this is the surprises when they found out there is an easier and convenient way to do their job. For example, the user may press the Delete key or right click and choose Delete in order to delete the selected files in Windows Explorer.
  14. Fine tuning the query response time by add appropriate indexes or using multi-thread - this is especially loading lots of records from the database or generating reports. Do you know how frustrated is that for the user to see "not responding" word appear in the program/task manager?
Assumptions:
  1. Always assume that you are not sure about the detail process - so ask for all the details and do not assume what you know is correct.
  2. Always assume that the user still have something exceptional procedures to follow - well, you have to prepare yourself before interviewing the users.
  3. Always assume that the user will request for changes in the database or system flow - this requires declaring constants or reading the settings from the database, writing modular program, passing the parameter with an object type instead of value type, etc.
  4. Always assume that the data will grow faster than the user is expecting - when the system has rolled out, it will grow faster than you are expected. The proper way to handle this is to calculate the number of transactions per week/month that will be entered into the database. Then, estimated the number bytes per transactions. Base on the total bytes that requires, you will be able to come out with an appropriate server/workstation specification.
 Is that all? NO. You have to learn from experience or from other experts and then build your own checklist.

Thursday, June 28, 2012

Running different codes between debug mode and release mode

This is one of the compiler feature that is not widely used or not known by most of the programmers. For example, in ASP.net, you might want to use the full Java Script file in the debug mode. But, in the release mode, you might want to include the "light" version (or minified version). This is because the minified version requires lesser time for the browser to download it.

public void IncludeScript()
{
    Page pg = HttpContext.Current.Handler as Page;
    string js_url;
    string key = "jquery";

    if (!pg.ClientScript.IsClientScriptIncludeRegistered(key))
    {
#if DEBUG
       // for debug mode, include the full JavaScript.
        js_url = pg.ResolveUrl("~/js/jquery-1.7.1.js");
#else
       // for release mode, include the minified version.
        js_url = pg.ResolveUrl("~/js/jquery-1.7.1.min.js");
#endif

        pg.ClientScript.RegisterClientScriptInclude(pg.GetType(),
                                                    key,
                                                    js_url);
    }
}

Other situation where you might want to use this concept:

  • Set the default user name and password in debug mode.
  • Get and/or save the runtime value in debug mode.
  • Create a debug log while debugging the program.
  • Modifying or setting variable's value at debugging time.

Please take note that the compiler directive does not limit to ASP.net. It is meant for all kinds of project types.

Saturday, June 9, 2012

Invoking a static method through reflection

For example, you have a program that requires to download the updated version from the Internet through an updater program. And this updater program is a standalone EXE program which was shared among other software projects.

In the main program, you may invoke the method provided in the updater program by calling InvokeMember.

public static bool RequiresUpdate(out Version latest_veresion)
{
 latest_veresion = null;
 string url = GetUpdateUrl();
 string info_file_name = GetInfoFile();
 
 AppDomain app_domain = AppDomain.CreateDomain("AutoUpdate.exe");
 Assembly asm = app_domain.Load(s);

 // get the class.
 Type type = asm.GetType("AutoUpdate.CAutoUpdate");

 object[] param = new object[]
      {
       url,
       info_file_name
      };

 // execute the static function
 string[] need_update = (string[])type.InvokeMember("CheckUpdateInfo", 
       BindingFlags.Default | BindingFlags.InvokeMethod, 
       null, 
       null, 
       param);

 if (need_update != null
  && need_update.Length > 0)
 {
  string[] v = need_update[0].Split('=');
  if (v.Length > 1)
  {
   latest_veresion = new Version(v[1]);
   Version current_version = Assembly.GetExecutingAssembly().GetName().Version;

   if (latest_veresion > current_version)
   {
    AppDomain.Unload(app_domain);
    return true;
   }
  }
 }

 AppDomain.Unload(app_domain);

 return false;   
}