Sunday, 29 May 2011

Using Color Picker Extender Control in ASP.Net

Yesterday , I was working on ASP.Net application. I want to use ColorPickerExtender Control in my application so that user can set background color of the web page according to his/her own choice. I extend my TextBox Control with ColorPickerExtender Control and set its target Control Id to the id of the TextBox Control.But when I set background property of the web page to the value of textbox then I found that data type of textbox value did not matched with the datatype of the background property of the web page. Because first one return String where last one need Color type value.

Now, my problem was how to convert the String data type to Color data type. After extensive research ,I found that I can create a class inherit from Iconverter and then write a code to convert String data type to Color type. Also, I found one another short alternative method to solve the above problem and that was ColorPickerExtender Control has SampleControlID property .

We can set this property to the ID of the Control on which  we want to perform operation.Like ID of the Panel , label ,Textbox and so on and ColorPickerExtender Control automatically change the Back Color of that control as I did in this code:

 

<asp:Table ID="Table1" runat="server"><asp:TableRow>

<asp:Panel ID="Panel2" runat="server">
</asp:Label><asp:TextBox ID="TextBox1" runat="server" AutoPostBack="True"></asp:TextBox><asp:ColorPickerExtender ID="ColorPickerExtender1" runat="server" TargetControlID="TextBox1" SampleControlID="Panel1"></asp:ColorPickerExtender></asp:Panel></asp:TableCell>
</asp:Table>
</asp:TableRow>
<asp:Label ID="Label1" runat="server" Text="Select a Color" Font-Bold="True">
<asp:TableCell>

 

In the above code,note the shaded portion which contain the ColorPickerExtender Control  with TargetControlID and SampleControlID property.I set TargetControlID to the TextBox1 which extend the TextBox Control and SampleControlId to Panel1 which was the id of the Panel in which whole web page contained.

 

When a user select a color from ColorPickerExtender Control then backcolor of panel1 will automatically change with respect to the selected color.

Highlighting selected item of the List Control in WPF.

In my last WPF assignment, I used data template to bind my data source with ListBox Control .Upon successfully binding data source with ListBox Control, when I select an item form a listbox control, I notice that highlighted color of the selected item in the ListBox was same as system default color. But, I want the color of selected item should be different from default color which makes a difference between selected and unselected item of the control.

So, I found that this can be done by using ItemContainerStyle property which is available in List Control. The ItemContainerStyle is responsible for the overall look of the List Control (ListBox Control in my case).

I attached  ItemContainerStyle property like this:

 <ListBox ItemContainerStyle="{StaticResource myContainerStyle}">

Here "myContainerStyle" is the name of the style which handles the selected item in the ListBoxItem.Then I defined the code for myContainerStyle like this:

 

<Style x:Key="myContainerStyle" TargetType="myListBoxItem">
     <Setter Property="FocusVisualStyle" Value="{x:Null}" />
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="myListBoxItem">
            <Border
           Name="Border"
           Padding="2"
           SnapsToDevicePixels="true">
              <ContentPresenter />
            </Border>
            <ControlTemplate.Triggers>
              <Trigger Property="IsSelected" Value="true">
                <Setter TargetName="Border" Property="Background" Value="Teal"/>
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

In the above code ,note the selected portion where I defined the "IsSelected Property" in the trigger.When ever user select the item from the list ,this trigger will fire and change the background color of the selected item to specified color(in this case it is Teal)

So,the final code for my ListBox control become:

       <ListBox x:Name="TemplatedListBox"
      HorizontalAlignment="Left"
      ItemTemplate="{StaticResource myDataTemplate}"
      ItemsSource="{Binding}"
      ItemContainerStyle="{StaticResource myContainerStyle }" >
     
 </ListBox>

Monday, 23 May 2011

Enhancing "Reusability" by creating own Custom Validation Controls in ASP.NET


In my last ASP.NET assignment, I have to validate controls on the web page like radio button, checkbox, Calendar and so on. When I tried to validate CheckBox Control with RequiredField Validator then I got a runtime exception informing me that the CheckBoxList cannot be validated with this validator. Then I tried with CustomValidator and it work. As my page contain different control so I want to use only a single validator to validate same type of control. For example a single validator to validate both CheckBoxList and RadioButtonList. Then I have searched on Google and find articles from which I came to know we can create our own Custom Validation Control. The main reason to create a custom validation control instead of using a CustomValidator is ‘reusability’ which was my problem.


With the reference of articles (mentioned in references section) I create my own validation control and reuse it for different control. Here I mentioned how I create my own Validation Control and provide both Server and Client Side Validation for the same.
Basic Overview of creating Custom Validation Control:
First thing we have create a class that inherits from BaseValidator
public class <Name of Validation class> : BaseValidator
Then you have to override a few methods:
·       ControlPropertiesValid:  returns whether the control can be validated by the validator or not
·       EvalutateIsValid:             returns whether the value in the input control is valid
·      OnPreRender:                 used to inject client side functions into the page
Let us we start to create a Custom Validation Control by right click on the project > Add New Item > From the Template, choose ‘Class’ > Rename the class to ‘MyValidator’ or anything you like > Choose the Language (C#) > Click on Add.
Visual Studio would prompt you to add the class to the App_Code. Choose yes to do so
As already discussed, we will be deriving from the BaseValidator abstract class. We will need to implement the ‘EvaluateIsValid’ method which returns a Boolean value indicating if the field/control being validated is valid or not.
The code for the server side validation will be similar (as I use C#) to the following:
namespace CustomListValidator

public class MyValidator : BaseValidator
{
    public MyValidator()
    {

    }

    protected override bool ControlPropertiesValid()
    {
        Control ctrl = FindControl(ControlToValidate)as ListControl;
        return (ctrl != null);
    }

    protected override bool EvaluateIsValid()
    {
        return this.CheckIfItemIsChecked();
    }

   protected bool CheckIfItemIsChecked()
    {
        ListControl listItemValidate = ((ListControl)this.FindControl(this.ControlToValidate));
        foreach (ListItem listItem in listItemValidate.Items)
        {
            if (listItem.Selected == true)
                return true;
        }
        return false;
    }

}
}
In the code snippet shown above, we override the EvaluateIsValid() method. The ‘ControlToValidate’ is cast to a ListControl, which is an abstract base class for all list-type controls. We then loop through all the ListItems and if one of the items in both the CheckBoxList as well as RadioButtonList is checked by the user, we return true, else we return false.
In order to use this custom validation control on the CheckBoxList and RadioButtonList kept in our page, we will use the <%@ Register %> directive as shown below:
<%@ Register TagPrefix="CLV" Namespace="CustomListValidator" %>
//Add created custom validation control next to the control which you want to validate as we use inbuilt validator

<div>
<asp:CheckBoxList ID="chBoxList1" runat="server">
</asp:CheckBoxList></div>

<CLV:MyValidator runat="server" ID="custLstVal" ControlToValidate=" chBoxList1" ErrorMessage="At least one item in the checkboxlist should be checked" />

<asp:RadioButtonList ID="rbList1" runat="server">
</asp:RadioButtonList>

<CLV:MyValidator runat="server" ID="custRadVal" ControlToValidate="rbList1" ErrorMessage="At least one item in the radiobuttonlist should be checked" />

<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
As you will observe, the two controls are being validated by the same custom validation control that we are building. Run the application and click on the button without checking any items in the two controls. Two error messages are displayed when the form is submitted.

Client-Side Validation

We saw how to perform server side validation. Let us see how we can now perform validation directly on the client side, without a postback. To perform client side validation, you would need to override OnPreRender and create the javascript function using a StringBuilder object and output it using Page.ClientScript.RegisterClientScriptBlock().
The code with the OnPreRender and JavaScript function will look similar to the following. This code is to be added in the same class where the server-side validation code was added.
protected override void OnPreRender(EventArgs e)
{
    // determines whether the validation control can be rendered
    // for a newer ("uplevel") browser.
    // check if client-side validation is enabled.
    If(this.DetermineRenderUplevel() && this.EnableClientScript)
    {
        Page.ClientScript.RegisterExpandoAttribute(this.ClientID,   
        "evaluationfunction", "CheckIfListChecked");
        this.CreateJavaScript();
    }
    base.OnPreRender(e);
}



protected void CreateJavaScript()
{
 StringBuilder sb = new StringBuilder();
 sb.Append(@"<script type=""text/javascript"">function  
 CheckIfListChecked(ctrl){");
 sb.Append(@"var chkBoxList =  
 document.getElementById(document.getElementById(ctrl.id).controltovalidate);");
 sb.Append(@"var chkBoxCount= chkBoxList.getElementsByTagName(""input"");");
 sb.Append(@"for(var i=0;i<chkBoxCount.length;i++){");
 sb.Append(@"if(chkBoxCount.item(i).checked){");
 sb.Append(@"return true; }");
 sb.Append(@"}return false; ");
 sb.Append(@"}</script>");
Page.ClientScript.RegisterClientScriptBlock(GetType(),"JSScript", sb.ToString());
}
As you observe, we override the OnPreRender method and use the RegisterExpandoAttribute to assign the function name ‘CheckIfListChecked’ an attribute called ‘evaluationfunction’. The javascript function(CheckIfListChecked) takes one parameter, the validator object and returns ‘true’ if Valid (item in both Radiobuttonlist or CheckBoxList is checked) and ‘false’ if Invalid (Item in either Radiobuttonlist or CheckBoxList is not selected).
Note: If you observe, there is a call to the base.OnPreRender() in the OnPreRender method. This is done to make sure that if the users have turned off javascript on their browsers, then this call passes the control back to the page and allows the rendering to continue by calling base.OnPreRender() .
The javascript function is created using a StringBuilder object and is output using Page.ClientScript.RegisterClientScriptBlock()
The last step would be to add the EnableClientScript="true" to our custom validation controls as shown below:
<CLV:ListValidator runat="server" ID="custLstVal" EnableClientScript="true" ControlToValidate="CheckBoxList1" ErrorMessage="At least one item in the checkboxlist should be checked" />

<CLV:ListValidator runat="server" ID="custRadVal" EnableClientScript="true" ControlToValidate="RadioButtonList1" ErrorMessage="At least one item in the radiobuttonlist should be checked" />

This time when we run the application, the custom validation control handles both server-side as well as client-side validation. If JavaScript is enabled on your browsers, the validation errors are displayed before the form is posted back to the server

References:

1.   Creating a Custom Validation Control in ASP. Posted by: Suprotim Agarwal, on 9/5/2008, in category "ASP.NET" . http://www.dotnetcurry.com/ShowArticle.aspx?ID=197

2.    http://codeclimber.net.nz/archive/2007/07/19/How-to-add-a-required-validator-to-a-CheckBoxList.aspx