Saturday, April 23, 2011

[ Dot Net Remoting ] - Using delegate for the Remote Functions in Both Sync, Async way


1. Introduction


In this article, I explain how will you use delegate on the functions exposed by the remote object. Also, I will explain how do we call those remote object functions in a synchronous way and in an asynchronous way. I do not want to explain threading here. But below is a very short note about Sync and Async function calls:

  1. The client function that makes a call to the remote function will wait for the completion of the remote function. This is a Synchronous call to the function exposed by the remote object.
  2. The client function that makes a call to the remote function will not wait for the completion of the remote function. This is Asynchronous call the function.

2. About the example


The Server in this example exposes a function that prints a running count taking some time. You can think of this function as long running task on the server. The function is just to simulate the long running process situation.

The client has two buttons and one function is calling the remote function in a synchronous way and other does the same in the Asynchronous way. The client uses the delegate of the same type to make a call to the remote functions.

When you click the Start Sync button, the count will be running on the server and once it is finished, the count on the form starts. The server shows the running count in the console window and client shows it in the text box. So, here the client will wait for the server completed the counts.

When you click the Start Async button, the count will run in parallel between a server and the calling client. That means, after the call the client will not wait for the server to complete its task. 

Fig 1. Example Application



3. Codes for The Server


The code for the server is similar to previous examples. So you will not see much explanation here repeated again. If you need much explanation on the server, please have a look at the First remoting article.

1) In the server, after creating the project a class called Counter is added and it is derived from MarshalByRef object. In the counter.cs file required namespace is included. This Counter class acts as the Remote class.

//RemSrv 01: Include required assemblies
using System.Runtime.Remoting;

2) The class has a constructor and a method PerformCount. This method will be called from the client using delegates. We will see about that in detail when we are moving to the client side coding. The code for this class is given below:

//RemSrv 02: Initialize the remoting object
public Counter()
{
    Console.WriteLine("Remote Object Created. " + Environment.NewLine);
}

//RemSrv 03: Perform the counting operation. This will take sometime and is useful to explain
//           How async call to this method is useful from the client end.
public void PerformCount()
{
    int x;

    for (x = 1; x < 10000; x++)
        Console.WriteLine("Current Count : " + x.ToString());

    Console.WriteLine("Counting is finished");
    return;
}

3) In the application entry, we are hosting the remote object under the name Counter. For more detail look at the basic article (the first one)

//RemSrv 04 : Required Assemblies
using System.Runtime;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace RemotingDelegate
{
    class Program
    {
        static void Main(string[] args)
        {
            //RemSrv 05 : Create a communication channel (Server) and register it
            TcpServerChannel SrvrChnl = new TcpServerChannel(13340);
            ChannelServices.RegisterChannel(SrvrChnl, false);

            //RemSrv 06 : Register the Remote Class so that the Object can go
            //and sit on the Remote pool
            RemotingConfiguration.RegisterWellKnownServiceType
   (typeof(RemotingDelegate.Counter),
                "Counter", WellKnownObjectMode.SingleCall);

            //RemSrv 07 : Halt the server so that Remote client can access the object
            Console.WriteLine("Server is Running...");
            Console.WriteLine("Press Any key to halt the Server");
            Console.ReadKey();
        }
    }
}


4. Codes for The Client


The client is the windows application and the form details and what each UI is explained in section 2 of this article.

1) The below namespaces are included in the form to access the Remoting as well as very basic thread function Thread.Sleep. Also, note that the project reference for the server also included. Once the application is built properly then you can split the exes into server and client machines for testing purposes.

//Client 01: Include the required namespace
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Threading;
using RemotingDelegate;

2) Once we are ready with the required namespaces, two delegates of the same are declared at the class level. Actually, one delegate is sufficient, I kept two just to differentiate the way I am going to use it.

//Client 03: Declare delegates for Sync Call and Async Call
public delegate void SyncCall();
public delegate void AsyncCall();

3) The LocalCounter function here does the same job of the function PerformCount on the server. So there are two long running tasks, one at the server side and the other one is at the client side.

//Client 06: Start the Local Counter. Assume that It is a long running task.
private void LocalCounter()
{
    long x;

    lblDisplay.Text = "Starting the Local Count...";

    for (x = 1; x < 10000; x++)
    {
        txtCount.Text = x.ToString();
        Application.DoEvents();
    }

   lblDisplay.Text = "Local Count is Done.";
}

4) The click event handler for the button Start Sync first creates the proxy for the remote object and stores that in the variable cntObj. Then a delegate object of type SyncCall is created and it is pointing the remote function PerformCount. The function PerformCount is passed to the delegate object by using the proxy cntObj. Once the delegate fnCounter is ready, a call to the remote function PerformCount is made using the delegate. And after that a call to the local task (LocalCounter) also made. Below is the code:

private void btnSync_Click(object sender, EventArgs e)
{
    //Client 02: Get the Proxy for remote object
    Counter cntObj = (Counter)Activator.GetObject(typeof(Counter),
        "tcp://localhost:13340/Counter");

    //Client 04: Call the remote method through the delegate. This call is Synchronous.
    SyncCall fnCounter = new SyncCall(cntObj.PerformCount);
    fnCounter();

    //Client 05: Call the Local Counter
    LocalCounter();
}

Note that after making a call to the remote object (by the statement fnCounter), the execution will pause till the remote function finishes its task. Once the task is completed on the server, the execution resumes here on the client and the function LocalCounter starts executing. You can observe this by running the sample, the count on the server is displayed in the console window, once the count is completed, you will see an increment in the counter on the textbox of the form.

5) For making the asynchronous call, the delegate is created is in the same way as we did in the previous step. Below is the code:

//Client 07: Create the proxy for remote Object 
//and set the delegate to the required
//remote function.
Counter cntObj = (Counter)Activator.GetObject(
    typeof(Counter), 
    "tcp://localhost:13340/Counter");
AsyncCall FnCounter = new AsyncCall(cntObj.PerformCount);

6) Once the delegate is created, instead of directly calling the function, we are using the BeginInvoke method on the delegate. The first parameter is actually a call back that a server will call once it completes the operation. That is not covered here and I am leaving it to you to explore yourself. I am passing null for both the parameter. The return value is stored in the IAsyncResult. This is to do a check on the Server operation to make a safe call on the EndInvoke.

//Client 08: Call the remote method through the delegate. This is an 
//Asynchronous call.
IAsyncResult AR = FnCounter.BeginInvoke(null , null);

7) After the above call, we are making a call to the local computer function. But, here the client after making a call to the PerfomCount using the BeginInvoke method on the delegate immediately moves to the next statement, which is a function-call for local counting.  So there is no waiting for the server to complete its task.

//Client 09: Call the Local Counter. The Local Counter also 
//    run in parallel now, and we no need to
//           wait for the remote call completion. 
//    The remote counting method, Once Done, calls our
//           call back method CallBackHandler.
LocalCounter();

8) Finally, after making both the function run simultaneously, we are waiting at the end of the routine to make a call to the EndInvoke, which is the pair of its corresponding BeginInvoke. The IsCompleted property of the return value of the BeginInvoke method is used to test whether server function tied to the delegate is finished or not. Once we know the server is done with the operation, we can make a call to EndInvoke by passing the value returned from the BeginInvoke function call.

//Client 10: Test the Remote counting is finished or Not before 
//    invoking the EndInvoke method on
//           the delegate
while (!AR.IsCompleted)
    Thread.Sleep(500);
FnCounter.EndInvoke(AR);

9) The entire event Handling routine for the Start Async button is shown below:

private void btnAsync_Click(object sender, EventArgs e)
{

    //Client 07: Create the proxy for remote Object and set the 
 //    delegate to the required remote function.
    Counter cntObj = (Counter)Activator.GetObject(
     typeof(Counter), 
     "tcp://localhost:13340/Counter");
    AsyncCall FnCounter = new AsyncCall(cntObj.PerformCount);

    //Client 08: Call the remote method through the delegate. This is an 
 //    Asynchronous call.
    IAsyncResult AR = FnCounter.BeginInvoke(null , null);

    //Client 09: Call the Local Counter. The Local Counter also run in parallel 
 //    now, and we no need to wait for the remote call completion. 
 //    The remote counting method, Once Done, calls our call back 
 //    method CallBackHandler.
    LocalCounter();

    //Client 10: Test the Remote counting is finsihed or Not before invoking 
 //    the EndInvoke method on the delegate
    while (!AR.IsCompleted)
        Thread.Sleep(500);
    FnCounter.EndInvoke(AR);
}


5. Screen Shot of Sync and Async Call


Sync Call:




Note: The Server finished the count and Client not Yet Started.

Async Call:




Note: When the server is at the courting 32 and client is at 4533. It shows both the function is running in parallel.

Source code : Download

The above app is created in VS2005. If you have advanced IDE, Say yes to the conversion UI displayed.

Sunday, April 17, 2011

[C#] - Container Controls 2: Panel

1. Introduction to Panel Container


The "Container Control, Panel" is all about this article. We will see how do you use the panel control to group the controls and then we will explore the important properties of this container along with this example.

Panel container is almost like a group box and I am not going to discuss the stuff, which is already explained in the previous post for the groupbox. Unlike the groupbox, the panel does not have a title on the top. But it has the support to provide the scroll bars. These scrollbars allow you place plenty of control in it and make you scroll when the form is not enough to fit all the controls.

In this article example, we will see how the scroll bar behaves for some other property on the panel. OK let us start.


2. About the Sample


The form has a panel in the top and it displays a sample label placed on the design time. Below the panel there are two buttons one will add the label at runtime and the other one will remove the label.

The Allow auto size for panel check box, when checked, allows the panel to adjust its size based on the controls in it at the moment. Just think about how the auto size property of the label works. Panel also works the same way the content of the panel is controls, that’s all. The radio button Grow only and Grow and shrink controls how the automatic size of the panel behave.

The check box DoctoTop allows the panel to be docked on the topside of the form. This allows the panel to be resized when the form resizes.

Once the auto scroll check box is checked when the auto size is in the unchecked state the panel will get scroll bars. The Width and Height text boxes control the display of scroll bar.

This sample does not do any great thing and it is just created to explain the panel container and scrolling of the controls in it. OK. Let us move. Before that, download the sample and have look at the control names and properties set to it.



3. Docking the Panel


Docking is sticking the control to the any possible edges of the container. In our sample the Dockto Top checkbox will dock the panel to the top edge of the container. If a control is docked in the top or bottom of the container, the control width is always equal to its container. When container is resized the width of the docked control changed there by resizing it and the height will be constant. Similarly, if the control is docked in the Left or Right side of the container, the height will change along with the container and control width remains constant.

The code for the Check box UI is below:

private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
    //Panel 01: Dock Property usage
    if (checkBox1.CheckState == CheckState.Checked)
        PanTopPane.Dock = DockStyle.Top;
    else
        PanTopPane.Dock = DockStyle.None;
}

The code sets the Dock property of the panel Control to top. Dockstyle.top is the enumeration constant. 

Why do I say the panel as control here? Well, the containers can behave as control also. Here, the Panel is a container for the sample label "label control". But the form treats the panel as a control or Panel’s container is the form. Simply, Form acts as container for the panel, and the panel acts as container for the  Label control. 

Dot net will see the "Dock Property" and knows where it should move and resize the control by looking at the container of the control. In our case, the panel is making a call to Dock() and Dot knows where to dock the panel as it knows the Container for the panel is the Form.

Run and Test > 01

1) Run the sample
2) Place a check mark on the Dockto Top
3) Now resize the form



Observe that the panel will resize along with the form only on the widthwise. Also, note that the panel is relocated from the design time position to the top of the form. Do not worry about the scroll bars now.

4. Panel autosize


The "AutoSize Property" of the panel will accept a Boolean true or false. When autosize is set to true, adding or removing the controls in the panel will automatically resize the panel. When this property is set to false and there is no scroll bar enabled to the container, the labels added beyond the visible portion will not be shown.

"AutoSizeMode Property" of the panel controls how the panel will be resized when the control is added to it or removed from it. The "GrowOnly Mode" of AutoSize property allows the panel to grow when the added control is in the invisible portion of the panel. And, the Panel Container will not shrink from the last set minimum size when a control is removed. The "GrowAndShrink mode" will allow the control freely resized based on addition or removal of the controls.

Below is the code for it:

private void chkAutoSize_CheckedChanged(object sender, EventArgs e)
{
    //Panel 02: Allow Auto Size to Panel. Then set the mode in which auto size works
    if (chkAutoSize.CheckState == CheckState.Checked)
        PanTopPane.AutoSize = true;
    else
        PanTopPane.AutoSize = false;
}

//Panel 03: Set the auto size mode
private void radGrowOnly_CheckedChanged(object sender, EventArgs e)
{
    if (radGrowOnly.Checked == true)
        PanTopPane.AutoSizeMode = AutoSizeMode.GrowOnly;
}

private void radGrowShrink_CheckedChanged(object sender, EventArgs e)
{
    if (radGrowShrink.Checked == true)
        PanTopPane.AutoSizeMode = AutoSizeMode.GrowAndShrink;
}

I hope no explanation is required on the code. You can understand it easily.

5. Adding and removing control at runtime


The panel and all the container classes maintain a collection of controls as property. The property name is "Controls". Here to add or remove the label controls we need to create control first and then add it to the panel through methods offered by the Controls property. Let us look at the code.

1) First, a variable is declared to know the position of the control when we add or remove. Here location_x will not change and when I am writing I am releasing it and I do not want to make a change now. The location_y will change when we add the label and remove it.

//Panel 05: Remember the Location for the Labels
int location_x;
int location_y;

2) In the constructor, we are setting the above variables from the control that is already available in the form for reference.

//Panel 06: Save the Location
location_x = LblReference.Location.X;
location_y = LblReference.Location.Y;

3) Next, the handler for the Add Label button will first create the label, sets the location using the variables talked in the previous two points, sets the size and text for it. Once the label is ready, it is added to the panel’s control collection. Rest the panel will do. Our job is to create the control and add it to the collection.

private void btnAddLabel_Click(object sender, EventArgs e)
{
    //Panel 07: Create the label and set its properties at runtime
    Label lbl = new Label();
    location_y = location_y + LblReference.Height + 11;
    lbl.Location = new Point(location_x, location_y);
    lbl.Size = new Size(LblReference.Width, LblReference.Height);
    lbl.Text = "Label " + location_y.ToString();

    //Panel 08: Add the control to the panel at runtime. This is to show you how the AutoSizeMode
    //          Propety for the panel Works
    PanTopPane.Controls.Add(lbl);
}

4) Below is the code for the removal of the label. Hope explanation is not required as it does the reverse of the previous one.

//Panel 09: Remove the label from the Panel
private void btnRemoveLabel_Click(object sender, EventArgs e)
{
    if (PanTopPane.Controls.Count == 0) return;
    Control.ControlCollection Controls_in_Panel = PanTopPane.Controls;
    Controls_in_Panel.RemoveAt(PanTopPane.Controls.Count - 1);
    location_y = location_y - LblReference.Height - 11;
}

Run and Test > 02

1) Run the sample by pressing the F5
2) When the form is visible, make sure the Allow Autosize for Panel checkbox is not checked.
3) Click the add Label to Panel button six times.
Only 4 labels were added and where is the next two? Here comes the usage of the autosize property.

4) Now check the add Label to Panel Checkbox.
Now you will see the remaining two controls. So the autosize property actually changes the size of the panel based on the content it has.

5) Now click the Remove Label from Panel button six times.
For the first two control removed, the panel got reduced in size. Then for other four controls removal the panel just maintains its size. It is because of the AutosizeMode property of the panel control. The Grow Only will not shrink the control from its original size. The original size is the one, which was before the change happened to it by the autosize property with the mode growonly.

6) Now check the radio button Grow and Shrink
7) Add six labels as you did previously by clicking the button
8) Remove the labels by clicking the corresponding button six times.
Now the Panel is reducing the size from its original size.




6. AutoScroll and AutoScrollMargin of Panel


The "AutoScroll Property" of the panel provides the scrollbars to the Panel when it is required. OK, "when it is required" is decided by the other property AutoscrollMargin. The scroll margin actually tells the minimum size allowed between the border of the control and edge of the panel. When the size further reduced by resizing the panel, a scroll bar will be added to it.

Below is the code for it.

//Panel 04: Set the autoscroll for the Panel.
private void chkAutoScroll_CheckedChanged(object sender, EventArgs e)
{
    if (chkAutoScroll.Checked == true)
        PanTopPane.AutoScroll = true;
    else
        PanTopPane.AutoScroll = false;

    //Oh!! I am lazy. You better type the numbers in the width and Height boxes.
    int width = int.Parse(txtWidth.Text);
    int height = int.Parse(txtHeight.Text);
    Size dimention = new Size(width, height);
    PanTopPane.AutoScrollMargin = dimention;
}

Note that the AutoScrollMargin accepts a size structure. And the structure defines scroll margin and instructs the panel when it should display the scroll bars. Look at the below picture:



To map it to our example, the black boxes are the controls and the gray box is the panel. A and B shown are scroll margins defined by AutoScrollMargin property. When the container resize operation hides the margin area, a scroll bar will be introduced when AutoScroll property is set to true.

Run and Test > 03 [Make sure autosize is unchecked]


1) Run the Sample
2) Place a check mark on dockto Top
3) Enter 300 in the width text box. Place a check mark on the Auto Scroll checkbox. This will show a Horizontal scroll bar because of the margin width of 300.
4) Scroll to the right of the Panel. The distance between the sample label edge and panel edge is 300. This is what we set in the ScrollMargin property. Have a look at the above drawing once again.
5) Scroll back again to the original position.
6) Add the label control by clicking the button multiple times. Notice that when the label added exceeds the edge of the panel a vertical scroll bar is added. Now scroll down to see the all controls.



Source Code : Download


Sunday, April 10, 2011

SQL 2005 - Group by, Order by, Having, Top With Ties Clause in SQL Server 2005


1. Introduction


In this article, we will explore the usage of the "Group By" and "Order By" clause. Also, we will see how does the TOP option behave with the Order by clause.

2. Example 01 – Order by


The below Example shows, the contact title is sorted in ascending order. This is done by using the Order By ContactTitle which is shown in the below example as the last line of query. The default is the ascending order.



3. Example 02 – Order by descending


The above query sorted the result in the Ascending order. Now look at the below example which sorts the same contact title column in descending order. We need to explicitly specify the "DESC" keyword in the Order By Clause.



4. Example 03 – Order by with more than one column


Now Look at the below example.



The query sorted the result based on two columns. First, it sorted the contact title in the ascending order and with-in that it sorted the result in descending order for the column Customer Id. The order by clause order by ContactTitle Asc, CustomerID Desc; in the above query has two columns, Contact Title first and Customer id next. Above screen shot shows [Red box] Contact title is sorted in ascending order. Look at the blue box; the result is sorted in descending order within the Marketing Assistance value of the Contact title.

5. Example 04 – Order by with Top


Now look at the below example that shows the usage of the "Top" clause in conjunction with the Order by clause.




In the above Query, we asked for top 10 records. SQL server first performs the sorting and then picks the top 10 records from it. The box shown in red indicates that it is not the complete records for the country Brazil. The next query shows how do you bring complete records for the column specified in the Order by clause.

6. Example 05 - Select top with ties


As discussed in the previous example, to bring the complete records for the country (used in the order by) that participate in the top 10, use the top 10 "with ties" option. Below is the query output:



7. Example 06 – Aggregate Function


"Aggregate functions" operate on the group of records and if a grouping is not specified it is applied to the entire records of a given table. The below example shows the usage of the count() function that tells how many records exists in the table in which it is called.



So, the result says product table has 77 records. You can also use the other aggregate function SUM, AVG for average, Min, Max, Count(*) for total records and Count(<column_name>) for count of Number rows which does not have null value for the <column_name>

8. Example 07 – Aggregate Function with where clause


The below example shows the usage of the aggregate function count on a query that used a “where” clause in it. First, the record filter is applied, then a count on the column Discontinued is calculated skipping the null entries in it during the count.



9. Example 08 – One more Example for Aggregate


The example below is same as the previous one except that we used a different aggregate function. The query is to get the to Unit price total of the product that falls under the category 2.




10. Example 09 – Aggregate with group by


All the aggregate function example shown above is applied to all the records returned by the query. So it considers the whole record set as a group and applied the grouping function such as sum, Min etc on it. The group by clause is used to get sub-group of the whole record set returned by the query.

The below query first groups all the records returned based on the Category Id. So if there are 3 categories then there will three subgroups. The count(ProductId) aggregate is applied on each group. So the result shows you number of product available in each category.





11. Example 10 – Aggregate with group by and Having clause


Have a look at the result of the above query. Now we will filter the product category, which has product count more than 10. As you know the count is an aggregate (Applied onset of records) & we cannot use a where clause to apply the filter on count aggregate. The filter should be performed on the on the group level.  The having clause works similar to the where clause. Simply, where clause is for filtering the records and "having clause" is to filter the sub-groups returned.

The below query will return the category which has more than 10 products.




12. Example 11 – How it works all together


Have a look at the below query and the result. There is nothing special in it. But, it has all you learnt in this article.



Below is the short explanation on how SQL server sees the above query and retrieves the data from the database:

  1. First, a column filter is applied and it takes only two columns CategoryID and ProductId.
  2. Then the Record filter is applied on the records using the condition specified in the where clause.
  3. Now the Filtered column and records formed in sub – groups using the CategoryId as the Group.
  4. After the group, a Not NULL count on ProductID on each sub-group based on CategoryId is calculated [Count(CategoryID)]
  5. The above-formed sub-group is again filtered based on the condition given in the Having clause.
  6. Finally, from what we have the sorting is performed. Here, the order by clause will do the sorting based on the sub-group count of valid productId.

Note: The above examples are formed using the NorthWnd Sample database. The SQL Script for NorthWnd is attached.



[C#] - Container Controls 1 - GroupBox

1. Introduction to GroupBox Control


In this article, we will explore the usage of the "Container Controls". The container controls are treated by the top most container say a dialog as a control. The container controls can hold some other controls. First, we will explore the Group box container control then we will move ahead with other container controls. There will be probably four or five parts and I will provide the links below once all the parts are published.

The Container controls have some special properties. They allow you to place controls on it and all the control inherit the properties from the container in which they sit. Say for example if you set the container disabled all the controls in the container becomes disabled. This is useful when you to form a group of controls that performs some action or collect logically similar information from the user.

Reserved Space for Links to other parts.
Container Controls. Part 1 : Group Box


2. About the GroupBox example




In the above example, we have two group boxes called country and actions. They both have logically grouped controls inside it. In the design time, I can easily move the controls that belong to Country group box easily without worrying about the control alignment and orientation. It holds true for the Actions group box also. As you already know these group boxes are actually containers so they allow you place some other control on it.

So there are totally three containers in this form including the form. The form treats the group boxes as controls. So the groupbox is a container as well as a control.

The enable checkbox, when checked, allows all the controls inside the Actions group box enabled. We are not setting the enable property for each control for doing this. What we do is simply set the property for the container that is set it for the Action group box. All other similar properties are demonstrated in the Actions group box.

Also, note that we have two radio groups. One belongs to the Country and one belongs to the action group box. So these two radio sets act independently.

3. Code for the Events


3.1 GroupBox Enable Property


First, the event handler for the checkbox based on the state change is created and inside the handler, we are checking the checkbox state and enabling or disabling all the controls that belong to the Actions Group box. Note that we are setting the property for the group box and all the controls inside the group box will automatically get the property from their container unless it is overridden by specifying it for a particular control.

private void chkAction_CheckedChanged(object sender, EventArgs e)
{
    //Groupbox 01: Enable or disable the Actions radio group
    if (chkAction.CheckState  == CheckState.Checked)
        grpActions.Enabled = true;
    else
        grpActions.Enabled = false;
}

3.2 GroupBox BackColor Property


Next, the radio button state change event is handled. Note that the radio button in this container acts separately from the one, which is already there in the country container. Here, we are setting the background property for the container and thereby for the control that it holds.

private void rdBack1_CheckedChanged(object sender, EventArgs e)
{
    //Groupbox 02: Set the Background for the Groupbox
    if (rdBack1.Checked == true)
        grpCountry.BackColor = Color.AliceBlue ;
}

private void rdBack2_CheckedChanged(object sender, EventArgs e)
{
    //Groupbox 03: Set the Background for the Groupbox
    if (rdBack2.Checked == true)
        grpCountry.BackColor = Color.Azure;
}

3.3 GroupBox visible Property


Next, comes the click event handler for the hide country button. Here, the button will toggle the operation between hiding and show of country group box. The button label also toggled between Show/Hide.

private void btnHideShowCountry_Click(object sender, EventArgs e)
{
    //Groupbox 04: Hide the Country Container
    if(btnHideShowCountry.Text == "Hide Country" )
    {
        grpCountry.Visible = false;
        btnHideShowCountry.Text = "Show Country";
    }
    else
    {
        grpCountry.Visible = true;
        btnHideShowCountry.Text = "Hide Country";
    }
}

3.4 Setting a Font to GroupBox


The handler for the set font button will bring the font dialog and sets the font for the country group box. All the radio buttons inside the country group box take the font that we set to the group box control.

private void btnFontVerdana_Click(object sender, EventArgs e)
{
    //Groupbox 05: Set a different font to the Country
    FontDialog fnt = new FontDialog();
    if (fnt.ShowDialog() == DialogResult.OK)
    {
        grpCountry.Font = fnt.Font;
    }
}

4. Closing notes


Note that all the control inside the container will inherit the properties from the container. Here I showed you some simple properties like Enable, Visible, Font etc that we set on the container is inherited by the controls in it.

If you want to be set a different, say, for example, different font for a specific control, then setting the property for that specific control overrides the one taken from the container.

In the Above Example:

1) Both the group boxes and the Enable actions check boxes belongs to the top-level container the form. So they inherit the properties from the form. In our example, I have overridden that to the group box control by setting my own properties that are a different color.

2) The group boxes which is a control for the top-level container the form is also a container for the control that it groups.


Now when you do set the properties at runtime always remember the Order:

1) Set the Properties for the Container and then override whatever you want for the control.
2) Let me assume that I need different back color at runtime for the Form, the group boxes and for the control Hide Country. In this case, your workflow should set the property for the form first and then for the Group box and finally for the Hide Country button.

The sample is created in VS2005. If you have advanced IDE say yes to the conversion UI

Download : Source Code

[ASP.Net] - Default Focus and Default button in ASP.net forms


1. Introduction


In this short article, I will show the importance of setting the focus to the control. Also, I will show the example for setting the default button for a form and also set a default for group controls.

Setting focus to a control is simple known one for most of us. A focus means the control is going to receive the input from the user. If you type something, the typed stuff goes into the control which currently on focus.

The default button is mapped to the enter keystroke on your keyboard. That is, the Enter button hit will call the button pushed event of the default button.

2. About the ASP form and the Example


Have a look at the simple asp form below:




  1. When the Page loaded, the default focus is set to the textbox control next to the name label field.
  2. When the tab key is hit, the focus moves in a sequential way.
  3. When you press the Claim button, some message is displayed in the label field shown in yellow colour.
  4. When the focus is in the any of three textboxes that correspond to name or discount id or order number, hitting the enter button on your keyboard invoked claim button press
  5. The next button to the claim sets the focus to the Order number text box
  6. When the control is in the Product name textbox, hitting the enter button will invoke the search button click.

All the above stuff accomplished by the default focus and default button properties. Of course, there is a minimal piece of code to display the message in the label and invoking a function that sets the control focus.

3. Setting the Properties


  1. Tab index property allows which control to should get focus when a keyboard tab key pressed. Each consecutive tab press allows the control focus in a particular sequence. This sequence is controlled by the tab index property. The framework maintains a count and increments it when a tab key is pressed. And resets it when a maximum number (Max of tab index in the form) reached. The tab index of the control is compared with this Framework count and control with the matched tab index is get focused. Now look at the tab index property for all the control one by one and run the page hit the Tab and shift + tab to experiment the result.
  2. The Associated control id property is set to each label control to move the focus to the control specified here. Because a label control usually won’t receive focus. The next box next to the label is set to the associated control.
  3. Default Focus property is used to set focus to a particular when the user interface loaded and shown initially.
  4. Default Button property can be used to link the enter button keystroke to a click event of the push button. A form can have one default button. Look at the above form; if the person typed a product name and hits enter, he does expect it will trigger the search button click not the claim button click. So in that case, the group product name label, textbox associated with it and the search button is kept in the panel control. First, a panel (Container) is placed on the form and then the three controls placed on it. Now we can have two default button properties; One for the form and one for the panel. To see the properties for the form, so to the source page and click on the form tag. I tried to pick the form from the design layout, but I cannot able to get it. Kind of searching the hidden cat “Kitty..Meow  KittyKitty Kitty..”. Well but you can easily select the panel to view its property. Now run the application, fill something on the claim form, and hit enter. Run again, put something in the product name text box and hit enter.


4. Code Explanation


The code is self-explanatory and there is nothing new to specify.

  1. One thing to mention is the usage of <br/> to form a multiline text in the label control displayed in yellow colour.
  2. To set the focus at runtime, just call the focus method of the control. The calling control will get the focus.

protected void Page_Load(object sender, EventArgs e)
{
    //Focus 001: Set the Default focus to the Name text Box
    txtName.Focus();
}
protected void txtFocustoLabel_Click(object sender, EventArgs e)
{
    //Focus 002: Set the focus to required control
    txtOrderNo.Focus();
}
protected void btnClaim_Click(object sender, EventArgs e)
{
    //Focus 003: Write some text to the Label
    LblDisplay.Text = "Discount amount Claimed! <br/>"  +
        "Name : " + txtName.Text +"<br/>" +
        "Discount Id (Found on Lucky Coupon) :" + txtDiscount.Text +"<br/>" +
        "Order No (for Reference): " + txtOrderNo.Text ;
}
protected void btnSearch_Click(object sender, EventArgs e)
{
    //Focus 004: Write Some text to the Label
    LblDisplay.Text = "Searching Product Id... <br/>" + txtProdname.Text +
        ". Please don't wait! It is Just a demo";
    txtProdname.Focus();
}



Source Code : Download
Like this site? Tell it to your Firend :)