Tuesday, February 21, 2012

[C#] - Using Masked Textbox and Mask property

1. Introduction to MaskedEdit Control

A "Masked Edit Control" is special form of edit control. In edit control, user enter the data and we do validation and manipulate that data to a specific format if required before persisting that information into the database. But, the masked edit control takes the data in the formatted way and at the mean time in validates the keyed-in data. Say for example we you expect a number; you can reject all other key INS.

The "Mask Property" controls the data format and data character validation. Like the text box control, the output from the masked edit also read from the text property. Have a look at the below depiction:



First, the edit box is set with the Mask property and the property is used to educate the control so that it can know what key press should be processed to take that as input. In the above picture 9 specifies that we expect a number in the placeholder as optional. That means when something entered it should be a number. As it is optional user no need to fill all the placeholders. Below the mask property box in the picture, a red text box shown and that is exactly what the user will see in the edit box. It gives him/her knowledge (Of course also with label Phone No: in front of it) of what need to be and in what format the text box is expecting it.



2. About the Sample

The screen shot of the sample for the Masked Edit is shown below:



The first text box looking control is the masked edit control that gets the user input in a structured way. There are some sample masks in the radio group which will allow you to set different mask for the masked edit control. You can actually provide your own format based on the need. The Show Output button will extract the text content from masked edit and display it in the text box control next to it.

Hide Mask on Leave check box shows the mask format in the control when the input focus is set to the control. Beep on Error informs the masked edit control to make the beep sound when a wrong character is entered in the masked edit box. Include literal and include Prompt will control the text output from the mask control to skip the literal character or the prompt letters. In the picture at section you can see what is literal and prompt chars. The sample also allows you set a different prompt character at runtime using single character masked edit control (Look at the bold values of properties to know the properties set to it. The set button will set the prompt char for the big masked edit control at the top of the form.

This is a simple sample and all we did is assigning the properties to demo how the masked edit is useful and how it saves time when you need a formatted input and need for validation like I need only chars or numbers like that. OK. Let us start exploring the code and I am leaving the form design to you and its simple drag drop of some controls.



3. The Mask property of MaskedEdit Control

This is the heart of the Masked Edit control and this property tells the masked edit how it should behave and what input key it should process and what it should not. Look at the radio group and it shows the first one says it expects some number and fourth one says it expects number (Again) in the form of hour, minute, seconds.

Let us take the fourth mask. The zeros in the mask say that a number (0-9) should be entered and the colon ‘:’ is the literal that cannot be changed. So when user types the time they no need to type the colons as it already there in the required position.

Below are the letters that you can mix with the literals:


  1. # - You can type +/- [Optional]
  2. 0 – Digit zero to 9 [Required]
  3. 9 – Digit 0 – 9 [Optional]
  4. A – Alpha Numeric. [Required]
  5. a – Alpha Numeric. [Optional]
  6. L – Letters a-z, A-Z [Required]
  7. ? – Letters a-z, A-Z [Optional]
  8. C – Any non-control character [Optional]

 You can refer the documentation for more mask letters. But, this is enough to frame a mask to get the controlled input. As you see, each character has a meaning and accept rule. Say for example, the character 0 states that it only accepts the number. OK. What if the use types M in the placeholder for 0? The input is not accepted. What is Optional and Required? When we type a wrong character in the placeholder the keyed-in character is skipped. This may make you think that you cannot move to next character until the required characters are filled. Right?

But, this is not how the control behaves. You can still the skip the required placeholder and take the output from the masked edit control. Then how the control responds when the required character is not filled? Well. It sets the "MaskCompleted Property" only when the required mask characters placeholders are filled. This property doesn’t care about the optional mask characters. The "MaskFull Property" is set to true when all the required as well as optional placeholders in the mask are filled.

Below is the code (handler for radio buttons) for setting the mask property:

//Mask 001: Set different Masks based on the selected radio buttons.
//              These masks control the output in a specific format.
private void radMask1_CheckedChanged(object sender, EventArgs e)
{
    maskedInput.Mask = radMask1.Text;
}

private void radMask2_CheckedChanged(object sender, EventArgs e)
{
    maskedInput.Mask = radMask2.Text;
}

private void radMask3_CheckedChanged(object sender, EventArgs e)
{
    maskedInput.Mask = radMask3.Text;
}

private void radMask4_CheckedChanged(object sender, EventArgs e)
{
    maskedInput.Mask = radMask4.Text;
}

private void radMask5_CheckedChanged(object sender, EventArgs e)
{
    maskedInput.Mask = radMask5.Text;
}

The below code shows the usage of the mask completed property. We examine the "Textchanged Event" of the masked edit control and display the mask-completed label when the "MaskCompleted Property" is set to true.

We just set the caption text of the radio control to the mask property of masked edit control. Below is the video that shows how the mask is shown to the user and how do we use the mask completed property.

//Mask 007: Show the Mask Completed label when required input is completed.
private void maskedInput_TextChanged(object sender, EventArgs e)
{
    if (maskedInput.MaskCompleted == true)
        lblMaskCompleted.Visible = true;
    else
        lblMaskCompleted.Visible = false;
}

Video





4. Hiding the mask on Leave

The Hide "HidePromptOnLeave Property" is used to hide the prompt character when we leave the masked edit control. In other words, the prompt characters are shows only when we set focus to the control. Below is the code for it:

//Mask 003: Hides the prompt chars on the mask when we leave the control
private void chkHideMsk_CheckedChanged(object sender, EventArgs e)
{
    maskedInput.HidePromptOnLeave = chkHideMsk.Checked;
}

How the above code make changes to the Masked edit control is shown in the below video.

Video





5. BeepOnError Property

The "BeepOnError Property" makes a bell sound if PC sounds only available. If you have proper sound card then it plays sound file (.Wav) for the error. You can set a different error sound in the control panel for sound option. Below is code that sets the BeepOnError to true when the checkbox is in the checked state.

//Mask 004: When user enters the invalid char raises the beep (Or plays corrosponding .wav file
//               when external sound device is connected)
private void chkBeepErr_CheckedChanged(object sender, EventArgs e)
{
    maskedInput.BeepOnError = chkBeepErr.Checked;
}



6. Setting different prompt char

The "PromptChar Property" is used to set different prompt character to the Masked edit control. In the sample a masked edit control is used to set the prompt character. And the mask property for the text box is single C. That means you can enter only one character and that can be any character except the control keys. Have a look at the properties set (Bold values) for the small edit box after downloading the sample. Below is the code that sets different prompt character to the masked text box control by changing it from default underscore(_).

//Mask 006: Setting the different mask prompt charactor
private void btnSet_Click(object sender, EventArgs e)
{
    maskedInput.PromptChar = System.Convert.ToChar(txtmskPromptChar.Text);
}

In the code we are converting the entered text (Single character) to Char data type as that is want expected by the property PromptChar. Below video shows the above code, PromptChar property in effect.

Video




7. TextMaskFormat Property

Go back to the section 1 of this article and have a look at the depiction to know what is Prompt character and what is mask literal. The text property will retrieve the value entered in the masked edit control and when retrieving you can actually skip or allow those prompt and mask literals. The textMaskFormat property informs the masked edit control, how the output from the control should be extracted from the masked edit control. Below is the code that shows the usage of this property.

//Mask 005: When we take the output from mask control, we have the option of skipping the
//              Prompt and/or literal.
private void chkIncludeLiteral_CheckedChanged(object sender, EventArgs e)
{
    SetOutputFormat();
}

private void chkIncludePrompt_CheckedChanged(object sender, EventArgs e)
{
    SetOutputFormat();
}

private void SetOutputFormat()
{
    if (chkIncludeLiteral.Checked == true)
    {
        if (chkIncludePrompt.Checked == true)
        {
            maskedInput.TextMaskFormat = MaskFormat.IncludePromptAndLiterals;
        }
        else
        {
            maskedInput.TextMaskFormat = MaskFormat.IncludeLiterals;
        }
    }
    else
    {
        if (chkIncludePrompt.Checked == true)
        {
            maskedInput.TextMaskFormat = MaskFormat.IncludePrompt;
        }
        else
        {
            maskedInput.TextMaskFormat = MaskFormat.ExcludePromptAndLiterals;
        }
    }           
}

By setting the proper constant value from the MaskFormat to the "TextMaskFormat Property", you can control how you want to extract the data entered in the masked edit control. The video below is showing how the output is changed by including or skipping the Prompt and literal characters.

Video



The masked text box control is useful when we want to educate user on what format of the input is expected from them. The mask character does not allow entering wrong characters in the placeholder. In the mean time it allows skipping the placeholder for required character by not entering anything. So the cider should make use of the MaskCompleted property to make sure all required character placeholders are filled. Finally we have the option of in what format we want to store the output and this format is controlled by TextMaskFormat property.

End.


Source Code : Download


Friday, February 03, 2012

SQL 2005 - Understanding Shared Lock and Exclusive Locks in Transaction Isolation

1. Introduction

SQL 2005 is a relational database model and multiple users can access the data that resides in the server box. Let us think there is an organization conducting a survey by taking help from their employees. Say the question is kind of "Do you like chocolate or Ice-cream?". Let us say that the cumulative outcome of their reply is updated in a single row. Now, when two employees (The client application they use for the survey) try to update the same row (A row has chocolate or Ice-cream column with a count of how many people likes it), does SQL Server discard an update from one person?

Let us take one more example. There is big stock market database maintained by "Abc" organization. A client web application say "App-A"  is retrieving a row as an enquiry from this database to know how a particular business stands in the stock market. But let us again assume when a row is read by "App-A"; an update is done on the same row by some other application say "App-B". Now the situation leads some columns of the row has older values and some columns has the updated values in "App-A" perspective.

SQL Server tackles the above situation by using the "Transaction Isolation". We will look at the different Transaction Isolations and its use in this article.

2. Shared Lock & Exclusive Lock

When reading or writing the data, SQL Server applies a lock on an affected row. The locks are two types. One is "Shared Lock" and other one is "Exclusive Lock". A shared lock is used by the read operation and an exclusive lock is acquired by the update operation. When a update puts a exclusive lock, read operation won’t happen on that row and read operation should wait till the update completes.

Have a look at the below picture:

Shared and Exclusive locks
Fig 1. Shared and Exclusive Lock


2.1 Exclusive lock by an Update

The first portion of picture shows you an update of row in progress and it is not yet completed. The Update operation applied an exclusive lock before starting the actual update of the required row in discussion. And a read operation along the way is waiting, as it cannot able to acquire the shared lock on that row. The Excusive lock not only blocks the read operation, it will block next coming update operation (On the same row) also. That means, only one update operation can have the exclusive lock on a particular row.

2.2  Read v.s Shared Lock

The second portion shows that the update operation is completed and the exclusive lock is removed. At this stage either an next waiting update can acquire a exclusive lock or a read operation can acquire a shared lock on the row. In our depiction, a read operation acquired a shared lock and started reading the data. In the default Isolation level (We will discuss the remaining later), an exclusive lock request by an update operation is not permitted when the row is already got a shared lock. Then why we call it as shared lock? Well.

2.3 Multiple Reads

Now look at the third portion of the picture. There are two more read operations going on in the same row now. It shows that all three read operation shared a single lock and that’s why we call it as Shared Lock. Simply, the lock is shared for the Read operations and Update is still not allowed when the lock is ON.

3. READ COMMITTED Isolation

This is the default transaction level of SQL server 2005. It will allow only one update on a row at a time and during that the read also prohibited. Have a look at the below two queries:

Read Committed Isolation
Fig 2. Read Committed Isolation
Fig 3. Select from Student table
    
With these two queries we can examine the default transaction called "Read Committed". I used a sample table called student in the above two queries. You can use NorthWnd or other demo database that you have on your machine. The update query in Fig.2 and the select query in Fig.3 can be run at two different machines.

Now let us go to the first SQL statement, which is nothing but a simple update on the Student sample table. The "begin transaction" says that we need to do manipulation or retrieval under the Transaction Isolation rules. The update statement enclosed within the Begin Transaction and commit transaction applies the exclusive lock on the student row with student id 103. When you execute the query shown in red box, that particular row is in locked (Exclusively) state and nobody can touch it except the one who applied that Exclusive (red) lock. Do not execute the commit transaction now, in stead go to the other machine (Or other Console management studio on you machine) and execute the select * from student. What happens? The read operation waits to acquire the transaction lock (Shared one) when the scanning came to the student 103 row. Now the situation is:

Since commit transaction is not executed SQL thinks student 103 is still a dirty row (Half updated) and keeps the exclusive lock on it. Select statement waits to acquire to shared lock on the exclusively locked row. You can see that other query window waits and waits and waits not showing the result of the select statement. Now, go ahead and execute the commit transaction statement. You will see the output of the select statement.

4. Other three Isolation

The other three isolation levels are listed below:

  1. READ UNCOMMITTED
  2. REPEATABLE READ
  3. SERIALIZABLE

Before we go into details of each one, first have look at the below SQL Statement that will change the Default Read Committed Isolation level to any of the above one.

Set transaction Isolation level Read UnCommitted;

The syntax is a simple Set statement. People usually decide the Isolation Levels, then execute the SQL statements with "Begin Transaction" and "Commit". After the execution of the batch, they reset the Isolation level back to the default. OK. Now let us go to the each one of these Isolation one-by-one.

4.1 Read UNCOMMITTED

The "Read Uncommitted" transaction Isolation level does not prevent read as well as the Write operation. This means that when a row is half updated and still in progress and read operation (Select statement) can still proceed there. We call this as "Dirty Read" or "Uncommitted data". Look at the T-SQL statements below:

Query Window 1:

Set transaction Isolation level Read UnCommitted;
Begin Transaction
Update student set class = 7 where studid = 103;
commit;

Query Window 2:

Set transaction Isolation level Read UnCommitted;
Begin Transaction;
      Select * from student;
commit;

In both the SQL transaction above (One Select and One Update), we set the transaction isolation level to UnCommitted using the "Set transaction". This means, we are requesting that we want to read data without any delays and at the same time we don’t care about the dirty data. Now execute the statement till update in the query window 1, delaying the execution of commit (Do not execute that now). Now execute the all the statements in the Query window 2. What happens? No delay on retrieving the set of records right? And see, you got Hansika as 7th STD girl. Even though the update in the query window 1 is not committed we are still seeing the updated result in the query window2. Now execute the commit statement in Query Window 1. 

4.2 Repeatable Read

The "Repeatable Read" isolation level will make sure to lock the retrieved rows from any further update. In the mean time, it will allow inserts as well as read on the table. Here the lock is applied to all the retrieved rows marked in the transaction. This transaction isolation make sure of “inserts? OK Proceed, Updates? Please Wait” on the locked set of Rows.  Now look at the below two Queries:

Query Window 1:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRANSACTION;
Select * from student;
Commit Transaction;

Query Window 2:

Select * from student where Studid = 108;
Insert into student values(110, 'Ramesh', 4);
Insert into student values(111, 'Rakesh', 2);
update student set class = 4 where studid = 108;

As you did in the previous sections, Execute the query till the select statement in the query window 1. Then execute the SQL Statements one-by-one from query window 2. You will see that select and couple of inserts are executed. But, the update statement waits and once you execute the commit transaction on the Query Window 1, the update in query window 2 proceeds Promoting the Student 108 to 4th standard of class.

Look at the name of the Isolation. Repeatable read, means that I will have multiple reads in the same table and going to fetch two or three or more number of records and I want to make sure nothing got changed in the retrieved rows until I mark my transaction as finished either by Commit transaction or Roll back transaction. Now look at below two statements:

Query Window 1:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRANSACTION;
Select * from student where studid = 108;
Commit Transaction;

Query Window 2:

update student set class = 3 where studid = 101;
update student set class = 4 where studid = 108; 

In the above transaction, the first update statement gets executed and next one gets blocked until the Transaction in the Query window 1 is committed. Because, we blocked only the rows with stuid = 108 in the Query Window 1 Transaction.

4.3 Serializable

The "Serializable Isolation" also performs a lock and but the lock is a "Table Level Lock" and the table prohibits any insert and update on it. That means the entire table is completely locked for any changes. No Inserts. No Updates. You can examine this by taking the Set of queries shown in the previous example. Make sure to change the Isolation level to serializable as shown below:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

Note that the Isolation allows Select statements on the table. That is all in this article. 
Like this site? Tell it to your Firend :)