Sukumar Raju's Blog

MCP

Sponsors

Tags

News

SharePoint SharePoint

More reading these days Patterns and practicces


Interesting to work with ASP.NET Membership provider

Suggested Reading C# Book


patterns & practices Application Architecture Guide 2.0


MVP Blog Badge.

Grab this badge here!


December 2009 - Posts

Populating Drop Down List Selected Item while DetailsView in Edit mode

Populating Drop down list when DetailsView is in Edit mode is explained in another article Binding Drop down list when DetailsView is in edit mode.

It is common requirement when you are redirecting from Master page to details page where DetailsView control is used to display single record on second page or GridView and DetailsView are used on a single page. When the user selects Edit button to edit data within DetailsView control, it is common requirement to populate the previous value as selected item in drop down list. So that end user can either change previous value in drop down list or stick to current value being populated.

This article explains how to achieve this requirement from code behind.

ASPX

Below is the ASPX code to display country. When DetailsView in in Read-only mode Label control is used to display the relevant record country from “country”  database column, when DetailsView is in edit mode controls within EditItemTemplate are used to populate data.

Here Drop Down List control is used to populate list of countries when DetailsView in edit mode.

<asp:TemplateField HeaderText="Country">
 <ItemTemplate>
   <asp:Label ID="lblCountry" runat="server" 
   Text='<%# bind("country")%>' />    
 </ItemTemplate>

 <EditItemTemplate>
    <asp:DropDownList ID="ddlCountry" runat="server"  
       AppendDataBoundItems="True" >
       <asp:ListItem Value="" Text="" />
    </asp:DropDownList>   
 </EditItemTemplate>
</asp:TemplateField>

Code behind

Details view Data Bound event is used to populate drop down list selected item as shown below.

//Populate previous value as selected item
protected void dvUserRecord_DataBound(object sender, EventArgs e)
{
   //check for DetailsView mode is Edit
   if (dvUserRecord.CurrentMode == DetailsViewMode.Edit)
    { 
            
      //Get reference to Country drop down list
    DropDownList ddlCountry = 
    dvUserRecord.FindControl("ddlCountry") as DropDownList;
    
     if (ddlCountry != null)
      {
      //Data binding Drop down list source code here
      //This is discussed in another article 
         
      //Then populate SelectedItem
        
      //Get current record country and set as 
      //selected item in Country drop down list
      DataRowView row = dvUserRecord.DataItem as 
      DataRowView;
      if (row != null)
      {  
         //Get current record country
          ListItem liCountry = ddlCountry.Items.
          FindByText(row["country"].ToString());
      
      //Set as selected List item in Drop down list
        if (liCountry != null)
         {
            ddlCountry.Items.FindByText(row["country"].
            ToString()).Selected = true;
        
           }
         }
      }
     
}

That’s it! you are ready to fly…

User friendly Tooltip using Ajax Hover Menu Extender control

Hi

I was looking for a tooltip control where we can embed html and display desired output to provide user friendly interface. Using default ASP.NET Tooltip control we can not embed HTML, even though it is feasible to use CSS style to change look and feel still it lacks number of features.

Using Ajax Hover Menu Extender control is is quite easier to implement a Tooltip where you can embed HTML tags to get desired output. when tooltip text is more, scroll bar is displayed to scroll through to read complete text.

Step 1

After downloading, adding the Ajax Control toolkit to your ToolBox in Visual Studio, register AjaxControlToolKit on top of your aspx as below.

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="AjaxControl" %>

Step 2

Add Script Manager on aspx page as below.

<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>

Step 3

Use Hover Menu Extender control where the TargetControl ID is your desired control, Tooltip text is displayed from the Label control and CSS class is for styling as shown below.

<asp:Image ID="imgName" runat="server" ImageUrl="~/Images/Tooltip.gif" />

<cc1:HoverMenuExtender ID="HoverMenuExtender2" runat="server"
TargetControlID="imgName"  PopupControlID="lblTooltipTxt" 
OffsetX="30" OffsetY="0" />

<asp:Label ID="lblTooltipTxt" runat="server" CssClass="tooltip"
            Text="Your Tooltip Text HERE"/>

Style sheet class

Here is the style sheet source code used for the tooltip.

.tooltip
{
border:2px solid #317082;	/* Border width */
left:18px;	/* Same as border thickness */
top:0px;
position:absolute;
width:500px;	 /*Width of tooltip content */
height:100px;	/* Height of tooltip content */
background-color:#FFF;	/* Background color */
padding:5px;	/* Space between border and content */
font-size:1.0em;	/* Font size of content */
overflow:auto;	/* Hide overflow content */
z-index:1000001;

}

output

When you hover on the image tooltip is displayed as shown below.

Tooltip5

Hope you find it useful!

Multi field validator using Enterprise Library - Validation Application block

There are number of built-in ASP.NET validation controls(RequiredFieldValidator, CompareValidator, CustomValidator and few more) exist. But there is no multi field validator. It is quite feasible to write custom validator to meet the requirement and there are third party controls available such as this one.

I was looking for a Required Field validator that checks all the controls(TextBoxes, Drop down lists and Listboxe controls) on the form and outputs appropriate message when atleast one of the controls is not used/selected. I want to stop the search if the end user has not entered any text in TextBox / selected Dropdownlist / List Box controls.

Validation Application block from enterprise library is catering more than what I was looking for. Above requirement is easily met with just few lines of code(shown below)I found it really interesting and easy to use Validation Application block from Enterprise Library as explained below.

Enterprise Library - Validation Application Block

Below custom validator class that can be in your App_Code folder or your desired location.

Step 1

Declare properties in a class with required Validation rules

//Required name spaces for validation block
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;

/// <summary>
/// Declare fields and properties with 
///desired validation rules
/// </summary>
public class EmployeeValidator 
{
//Private Members
private string FirstName = string.Empty;
private string LastName = string.Empty;
private string Country = string.Empty;

//Properties with validation rules
[StringLengthValidator(1, 10, MessageTemplate=
"Please enter your search criteria")]
public string _FirstName
{
get { return FirstName; }
set { FirstName = value; }
}
[StringLengthValidator(1, 10, MessageTemplate =
"Please enter your search criteria")]
public string _LastName
{
get { return LastName; }
set { LastName = value; }
}
[StringLengthValidator(1, 10, MessageTemplate =
"Please enter your search criteria")]
public string _Country
{
get { return Country; }
set { Country = value; }
}

}
Step 2

Implement your validation rules by creating an instance of your validation object and associating your properties with ASP.NET Controls input as shown below.

protected void btnSearch_Click(object sender, EventArgs e)
{
//Message lable
lblValidationMsg.Text = "";

//Create an instance of Custom validator class
EmployeeValidator Employee = new EmployeeValidator();
//Assign form controls text to your business object - properties
Employee._FirstName = txtFirstName.Text;
Employee._LastName = txtLastName.Text;
Employee._Country = ddlCountry.SelectedValue;

//Create an instance of Validator and associate
//to your objects
Validator<EmployeeValidator> validator = ValidationFactory.
CreateValidator<EmployeeValidator>();
ValidationResults results = validator.Validate(Employee);

// Check if valid
if (!results.IsValid)
{
if (results.Count < 3)
{
//your button_click event code goes here
}
else
{
// If not valid, loop through the ValidationResults
foreach (var result in results)
{
lblValidationMsg.Text = result.Message;
}
}
}
}

Above few lines of code do the rest for you. You are ready to take off!

References

GridView sorting and paging using custom data method

Hi

When you are using a custom method or data object that returns a Dataset or DataTable and binding that to data control such as GridView or DetailsView, sorting and paging is little tricky than usual.

using stored procedure with custom method to bind data to GridView is explained in Dynamic Search using SQL Stored Procedure

Next requirement is to GridView Sorting and Paging. This article explains how to implment GridView paging and sorting using custom method.

/// <summary>
/// Handle Gridview paging event
/// and bind Search results data to GridView
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void GridView1_PageIndexChanging
(object sender, GridViewPageEventArgs e)
    {
GridView1.PageIndex = e.NewPageIndex;
//Bind search reuslts
GridView1.DataSource = SortDataTable(Search() as DataTable, true);
GridView1.DataBind();
     
  }

    #endregion

#region Properties SortDirection and SortExpresssion 

    /// <summary>
    /// property GridView Sort Direction
    /// </summary>
    private string GridViewSortDirection
    {
get
{ 
return ViewState["SortDirection"] as string ?? "ASC";
}
set 
{ 
ViewState["SortDirection"] = value; 
}

    }
    /// <summary>
    /// GridView sort expression
    /// </summary>
    private string GridViewSortExpression
    {
        get 
{ 
return ViewState["SortExpression"] 
as string ?? string.Empty; }

   set { ViewState["SortExpression"] = value; }
    }
    #endregion

    #region SortDirection method
    /// <summary>
    /// Get current sortDirection and switch between
    /// </summary>
    /// <returns></returns>
    private string GetSortDirection()
    {
        switch (GridViewSortDirection)
        {
            case "ASC":
                GridViewSortDirection = "DESC";
                break;
            case "DESC":
                GridViewSortDirection = "ASC";
                break;
        }

        return GridViewSortDirection;
    }

    #endregion

    #region SortDataTable

    /// <summary>
    /// Sort Data Table when Page Index changing
    /// </summary>
    /// <param name="dataTable"></param>
    /// <param name="isPageIndexChanging"></param>
    /// <returns>sorted DataView</returns>
protected DataView SortDataTable(DataTable dataTable,
 bool isPageIndexChanging)
    {
        if (dataTable != null)
        {

DataView dataView = new DataView(dataTable);
if (GridViewSortExpression != string.Empty)
{
if (isPageIndexChanging)
{
dataView.Sort = string.Format("{0} {1}", 
GridViewSortExpression, GridViewSortDirection);
}
else
{
dataView.Sort = string.Format("{0} {1}", 
GridViewSortExpression, GetSortDirection()); 

                }

            }
            return dataView;
        }
        else
        {
            return new DataView();
        }


    }
    #endregion

       
    #region GridView columns sorting


    /// <summary>
    /// Handle page sorting
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
    {

//Get sortExpression
GridViewSortExpression = e.SortExpression;
int pageIndex = GridView1.PageIndex;
//Bind GridView with search results
GridView1.DataSource = SortDataTable(Search() 
as DataTable, false);
GridView1.DataBind();
//Set the page Index
pageIndex = GridView1.PageIndex;

        
    }

    #endregion

References

Dynamic Search using Stored procedure

Hi

It is best practise to separate Data access layer from Business logic layer. It allows   easy source code maintainability, reusability and improves application performance. There are lot more advantages in doing so.

In order to implement a search engine where a ASP.NET form consists of various control to take user input, when you want to process your data access in code behind or using a separate class as data access layer it is mandatory to pass number of parameters and more number of lines of source code. Note that it is also same when you want to read user input,  process data access in code behind and bind retrieved data to data controls such as GridView or DetailsView etc.

Stored Procedure allows you to maintain your data access code in database side, providing security and improving performance with very few lines. It reduces number of lines of source code required to achieve the same in traditional approach.

This article explains how to write a stored procedure to process user input,return a Data Table and bind that Data Table to GridView control.

Presentation Layer (aspx)

<table cellpadding="0" cellspacing="0" width="70%">
<colgroup>
    <col width="15%" class="TableCol" />
    <col width="85%" />
</colgroup>
<tr>
    <td>
        <asp:Label ID="lblFirstName" runat="server" 
Text="First name" />
    </td>
    <td>
        <asp:TextBox ID="txtFirstName" runat="server"></asp:TextBox>
    </td>
</tr>
<tr>
    <td>
<asp:Label ID="lblLastName" runat="server" Text="Last name" />
    </td>
    <td>
<asp:TextBox ID="txtLastName" runat="server"></asp:TextBox>
    </td>
</tr>
<tr>
    <td>
<asp:Label ID="lblEmail" runat="server" Text="Email" />
 </td>
 <td>
<asp:TextBox ID="txtEmail" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<asp:Button ID="btnSearch" runat="server" Text="Search" 
OnClick="btnSearch_Click" ValidationGroup="btnSearch" />
</tr>
</table>

Business logic layer (code behind page)

/// <summary>
/// Execute the SP by passing search criteria
///using parameters
/// </summary>
/// <returns>DataTable with search results</returns>
private DataTable Search()
{

//DataTable to hold search resutls
DataTable SearchResultsTable = new DataTable();
//Read connectionString from web.config
SqlConnection conn = new SqlConnection(ConnectionString);

try
   {
//Create SQL command object by passing 
//connection and stored procedure name
SqlCommand cmd = new SqlCommand("spSearch", conn);
//command type to Stored procedure
cmd.CommandType = CommandType.StoredProcedure;

//pass search criteria using parameters
cmd.Parameters.AddWithValue("@firstName",txtFirstName.Text);
cmd.Parameters.AddWithValue("@lastName" , txtLastName.Text);
cmd.Parameters.AddWithValue("@email " , txtEmail.Text);

//create sql adapter by passing command object
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
//fill the search results table
adapter.Fill(SearchResultsTable);
}

catch (Exception ex)
        {
Response.Write(ex.ToString();
        }
        finally
        {
            if (conn != null)
            {
                conn.Close();
            }
        }
        
        //Return search results DataTable
        return SearchResultsTable ;
    }

}

Search button click event

protected void btnSearch_Click(object sender, EventArgs e)
{
//Bind search results to GridView control
GridView1.DataSource = Search();
GridView1.DataBind();
}

Stored Procedure

Stored procedure that reads parameterised input from code behind, executes the SQL and returns search results.

Create Procedure spSearch
( 
@firstName nvarchar(50) = null,
@lastName nvarchar(50) = null,
@email nvarchar(50) = null
) 
AS 
BEGIN
//Set NULL when variable is NULL or lenght is zero
If @firstName is not null and Len(@firstName )=0 Set @firstName = null
If @lastName is not null and Len(@lastName )=0 Set @lastName = null
If @email is not null and Len(@email )=0 Set @email = null

Select 
*
From Students
Where 
( @firstName is null or firstName Like @firstName )
and ( @lastName is null or lastName Like @lastName )
and ( @email is null or email Like @email )
END 

--Note that you can replace 'Like' keyword above to
-- IN to implement other than exact match as you wish

Thats it you are done!!

As the above demo uses few variables to prove the concept, in real time stored procedure can handle more parameters and makes it quite easier to implement search functionality.

References:

http://msdn.microsoft.com/en-us/library/k10148y1.aspx

http://msdn.microsoft.com/en-us/library/k10148y1.aspx

More Posts