http://fredrik.nsquared2.com/viewpost.aspx?PostID=186
Category:  ASP.Net 2.0


When I have helped people with extending the GridView control shipped with ASP.Net 2.0. I got the idea to write this post.

 

Some questions that I have seen are about how to extend the GridView control, such as setting the background color of the row when the mouse is moving over a row, turn a row into edit mode when the user has double clicked on a row etc. I wrote about how to set the background color in a previous post. In this post I have added a more functional client side script that will set back the original color of the row when the mouse has left the row.

 

Here are the changes from my previous post:

 

I have added two javascript functions, SetNewColor (Will set the color of the row when the user is moving the mouse over it) and SetOldColor (Will set back the original color of the row when the user leaves the row):

 

<script language=javascript>

 

    var _oldColor;

   

    function SetNewColor(source)

    {

        _oldColor = source.style.backgroundColor;

        source.style.backgroundColor = '#00ff00';

    }

   

    function SetOldColor(source)

    {

        source.style.backgroundColor = _oldColor;

    }

   

</script>

 

I have also change the RowCreated event to use those new client side functions:

 

void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)

{

    e.Row.Attributes.Add("onMouseOver", "SetNewColor(this);");

    e.Row.Attributes.Add("onMouseOut", "SetOldColor(this);");

}

 

You will find the whole example with a lot of other features at the end of this post.

 

Have you ever wanted to double click on a row and make the row to be changed into an editable mode? Or maybe select a row and press the enter key and do something rational ;)

 

What I’m going to show you know, is how you can use the client side __doPostBack method to do a postback when you double click on a row.

 

As you may know the __doPostBack method will be added by ASP.Net 2.0 at runtime, so we don’t need to add the method, we only need to know how to use it. The __doPostBack looks like this:

 

__doPostBack(eventTarget, eventArgument)

It has two arguments, eventTarget and eventArgument. The eventTarget takes the id of the control which this method is added to as a value.  The eventArgument takes a string with extra information that could be collected on the server side.

 

To the RowCreated event of the GridView control you can add something like this to make a postback when you click in a row:

 

e.Row.Attributes.Add("onClick","__doPostBack('GridView1','myEventArgs');");

 

To get the value from the arguments of the __doPostBack method after a postback has been done, you can use the Request.Form and get the value from two hidden fields that also will be added by ASP.Net:

Request.Form["__EVENTTARGET"]
Request.Form["__EVENTARGUMENT"]

The __EVENTTARGET will have the value of the __doPostBack’s eventTarget argument and the __EVENTAGUMENT will have the value of the evnetArgument.


This is an easy way of using the __doPostBack method to do a postback and also to get the values passed as arguments by the __doPostBack method. There is a more elegant solution for handling postback, and it’s to use the IPostBackEventHandler interface.

 

When you implement this interface you also need to implement the RaisePostBackEvent method. This method will be automatically called when a postback is done. When you use the IPostBackEventHandler you can use the GetPostBackEventReference method of the Page object to create the __doPostBack method instead of adding it by your self. The RaisePostBackEvent method has one argument of the type string. This argument will have the value of the eventArgument argument of the __doPostBack method.

 

To implement the IPostBackEventHandler for a Page you use the Implements directive:

 

<%@ Implements Interface="System.Web.UI.IPostBackEventHandler"%>

 

Instead of adding the __doPostBack by hand, you can use the GetPostBackEventReference method:

 

public string GetPostBackEventReference(Control control)

public string GetPostBackEventReference(Control control, string eventArgument)

 

 This method has two overloaded methods. The first overloaded method takes one argument with the control that postback is made from. The other method takes two arguments, the control and an argument with extra information as a string. The GetPostBackEventReference will return a generated __doPostBack method for us, where the __doPostBack’s eventTarget argument will have the value of the control’s Id passed as an argument to the GetPostBackEventReference, and the eventArguent argument will have the value of the GetPostBackEventReference’s eventArgument.

 

Now let’s see how you can use the GetPostBackEventReference method for making a postback when you double click on a row:

 

e.Row.Attributes.Add("onDblClick", Page.GetPostBackEventReference(this, e.Row.DataItemIndex.ToString()));

 

The code above is located within the RowCreated event of the GridView control. As you can see in the code, the GetPostBackEventReference is used to return a value for the onDblClick attribute for the rows. The Page object (this) is passed to the GetPostBackEventReference as an argument and the index of the created row is also passed to the method.

 

When you implement the IPostBackEventHandler, you also need to add the RaisePostBackEvent method to the page. This method will be called after you have double click on a row and the __doPostBack method has been called.

 

public void RaisePostBackEvent(string eventArgument)

{

       Response.Write(eventArgument);

}

 

Note: There can only be one RasiePostBackEvents method on the Page. If you have used the GetPostBackEventReference for other client side events of the GridView row or for other controls on the page, you have to use the RaisePostBackEvent method’s eventArgument’s value to identify what you should do based on which control that did call the  __doPostBack method.

 

If you have created a custom render control in .Net, and have added events for the custom control, you are probably already familiar with the IPostBackEventHandler.

 

Now let’s take a look at the example that will use the IPostBackEvent handler and make a postback when you double click on a row or press on one row and then press en enter key on the keyboard:

 

<%@ Page Language="C#" %>

<%@ Implements Interface="System.Web.UI.IPostBackEventHandler"%>

 

<script language=javascript>

 

    var _oldColor;

   

    function SetNewColor(source)

    {

        _oldColor = source.style.backgroundColor;

        source.style.backgroundColor = '#00ff00';

    }

   

    function SetOldColor(source)

    {

        source.style.backgroundColor = _oldColor;

    }

   

 

</script>

 

<script runat="server">

 

    void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)

    {

        e.Row.Attributes.Add("onMouseOver", "SetNewColor(this);");

        e.Row.Attributes.Add("onMouseOut", "SetOldColor(this);");

        e.Row.Attributes.Add("onDblClick", Page.GetPostBackEventReference(this, e.Row.DataItemIndex.ToString()));

        e.Row.Attributes.Add("onKeyDown", "if( event.keyCode == 13 ) " + Page.GetPostBackEventReference(this, "KEYDOWN" + "$" + e.Row.DataItemIndex.ToString()));

    }

 

    // Part of the IPostBackEventHandler interface.

    // you must create this method.

    public void RaisePostBackEvent(string eventArgument)

    {

        GridViewSelectEventArgs e = null;

        int selectedRowIndex = -1;

 

        if (!string.IsNullOrEmpty(eventArgument))

        {

            string[] args = eventArgument.Split('$');

 

            if (string.Compare(args[0], "KEYDOWN", false, System.Globalization.CultureInfo.InvariantCulture) == 0 && args.Length > 1)

            {

                Int32.TryParse(args[1], out selectedRowIndex);

                e = new GridViewSelectEventArgs(selectedRowIndex);

                OnReturnKeyDown(e);

            }

            else

            {

                Int32.TryParse(args[0], out selectedRowIndex);

                e = new GridViewSelectEventArgs(selectedRowIndex);

                OnDblClick(e);

            }

        }

    }

 

    protected virtual void OnDblClick(EventArgs e)

    {

        Response.Write("You double clicked on the row with index: " + ((GridViewSelectEventArgs)e).NewSelectedIndex.ToString());

        GridView1.EditIndex = ((GridViewSelectEventArgs)e).NewSelectedIndex;

    }

 

    protected virtual void OnReturnKeyDown(EventArgs e)

    {

        Response.Write("You press enter on the row with index: " + ((GridViewSelectEventArgs)e).NewSelectedIndex.ToString());

    }

   

</script>

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

    <title>Untitled Page</title>

</head>

<body>

    <form id="form1" runat="server">

        <div>

            <asp:GridView ID="GridView1" Runat="server" DataSourceID="SqlDataSource1" DataKeyNames="CustomerID"

                AutoGenerateColumns="False" OnRowDataBound="GridView1_RowDataBound"

                AlternatingRowStyle-BackColor="#6699ff" RowStyle-BackColor="#ccccff">

                <Columns>

                    <asp:CommandField ShowEditButton="True"></asp:CommandField>

                    <asp:BoundField ReadOnly="True" HeaderText="CustomerID" DataField="CustomerID" SortExpression="CustomerID"></asp:BoundField>

                    <asp:BoundField HeaderText="CompanyName" DataField="CompanyName" SortExpression="CompanyName"></asp:BoundField>

                    <asp:BoundField HeaderText="ContactName" DataField="ContactName" SortExpression="ContactName"></asp:BoundField>

                </Columns>

            </asp:GridView>

            <asp:SqlDataSource ID="SqlDataSource1" Runat="server" SelectCommand="SELECT [CustomerID], [CompanyName], [ContactName] FROM [Customers]"

                ConnectionString="<%$ ConnectionStrings:AppConnectionString1 %>">

            </asp:SqlDataSource>

        </div>

    </form>

</body>

</html>

 

In the code above, I have used the event argument to know if someone have double clicked on a row or have pressed the enter key. The code will check if the event argument of the RaisePostBackEvent has the prefix KEYDOWN$. If it do not have the KEYDOWN$ prefix, the OnDblClick method will be called. This method will get the index of the double clicked row from the event argument and use the index to switch the row into its edit mode. When the return key is pressed after a row has been selected, the OnReturnKey method will be called.

Extend the GridView bug Tuesday, May 30, 2006

Category:  ASP.Net 2.0

Hi everyone it was a while ago since I wrote a post. I have been on an amazing vacation to Azores a wonderful place. I was there with my girlfriend “Lovisa” and we had a wonderful time. I really recommend it for people that like nature. But it I should not write about that. I should instead write about a solution to solve a problem that Monte Aspevig notices me about. It’s about the article about extending the GridView control (I hope he don’t mind that I copy his message and paste it here)

 

Unfortunately with paging and sorting enabled the functionally stopped working as soon as I left the initial page.  After some investigation it appears the following line is the culprit:

 

e.Row.Attributes.Add("onDblClick", Page.GetPostBackEventReference(this, e.Row.DataItemIndex.ToString()));

 

I changed it as follows to correct for the paging/sorting issues caused by the “relative/page-specific” versus the “absolute” row index:

 

e.Row.Attributes.Add("onDblClick", Page.GetPostBackEventReference(this, e.Row.RowIndex.ToString()));

 

Thanks again Monte Aspevig for this information!