22 July 2011

DataGrid Sorting with Image from Boolean Value

It took me a while to find out how to display an image in a DataGrid depending on a boolean value.
I also wanted to sort this DataGrid depending on the click on the header column of the DataGrid.
This is what it sould look like:
This what it should look like

Afterwards you will find a detailed explanation of how this task can be done.

The Demo data is shown in the picture below:
Demo Data from Function: GetData()

For the sake of completeness here the picture of my solution structure which is a very basic sample:

Lets start: In the beginning I placed a GridView Control from the toolbar on the Default.aspx page.
  • Set AutoGenerateColumns="false"
  • Set AllowSorting="true"
  • Add Event onsorting="myGrid_Sorting"
  • Set the SortExpression for each field

The Markup for Default.aspx:
<asp:GridView ID="myGrid" runat="server" onsorting="myGrid_Sorting" AutoGenerateColumns="false" AllowSorting="true">
    <Columns>
        <asp:BoundField DataField="Surname" HeaderText="Surname" SortExpression="Surname" />

        <asp:TemplateField HeaderText="Status" SortExpression="UserState">
            <ItemTemplate>
                <asp:Image ID="imgStatus" ImageUrl='<%# GetIsActiveImage(Eval("IsActive")) %>' runat="server" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

In this case i want to bind the field "Surname" directly to the datagrid without modifying the data. So I use a BoundField to achieve this.
The more interesting step is binding the Image depending on the boolean values. Therefore I use a TemplateField containing an ASP.NET Image Control. Have a look at ImageUrl. A Helper method "GetIsActiveImage" is called from the code behind. This method is passed a Parameter from the original DataSource. Depending on true or false the specific image is displayed.

Here goes the code behind of my Default.aspx.cs file:
public partial class Default : System.Web.UI.Page
{
    private DataView dv;

    protected void Page_Load(object sender, EventArgs e)
    {
        DataTable dt = GetData();

        // Add Default View
        dv = dt.DefaultView;

        myGrid.DataSource = dt;
        myGrid.DataBind();
    }

    /// 
    /// Gets the data.
    /// 
    private DataTable GetData()
    {
        // Create DataTable
        DataTable myData = new DataTable();
        // Add Columns
        myData.Columns.Add("Surname", typeof (string));
        myData.Columns.Add("IsActive", typeof(bool));
            
        // Add first datarow
        DataRow row = myData.NewRow();
        row["Surname"] = "Daniel";
        row["IsActive"] = true;
        myData.Rows.Add(row);
        // Add second datarow
        row = myData.NewRow();
        row["Surname"] = "Robert";
        row["IsActive"] = false;
        myData.Rows.Add(row);

        return myData;
    }

    /// 
    /// Gets the is active image.
    /// 
    public static string GetIsActiveImage(object isActive)
    {
        if ((bool)isActive)
        {
            return "/Images/Green.png";
        }
        return "/Images/Red.png";
    }

    /// 
    /// Handles the Sorting event of the myGrid control.
    /// 
    protected void myGrid_Sorting(object sender, GridViewSortEventArgs e)
    {
        string lastExpression = "";
        if (ViewState["SortExpression"] != null)
            lastExpression = ViewState["SortExpression"].ToString();

        string lastDirection = "asc";
        if (ViewState["SortDirection"] != null)
            lastDirection = ViewState["SortDirection"].ToString();

        string newDirection = "desc";
        if (e.SortExpression == lastExpression)
            newDirection = (lastDirection == "asc") ? "desc" : "asc";

        ViewState["SortExpression"] = e.SortExpression;
        ViewState["SortDirection"] = newDirection;

        dv.Sort = e.SortExpression + " " + newDirection;
        myGrid.DataBind();
    }
}

The sorting is done via a DefaultView. In my opinion the simplest way to sort. SortDirection and SortExpression are held via ViewState.

Enjoy!

0 comments:

Post a Comment