AspAlliance.com: Alex Lowe's ASP.NET Tips and Tricks
AspAlliance.com: The #1 ASP.NET Developer Community
   Home       Contact Alex       Useful Links       About Alex       Other AspAlliance.com Articles     

Creating a DataGrid that auto-scrolls


I participate on the [aspnet-datadisplaycontrols] list (sign up here). One of the frequently mentioned gripes (FMG) about the DataGrid control is that it does not automatically scroll the user to a row when the row is put into "edit" mode (i.e. the edit link of an EditCommandColumn is clicked). So, I thought I would see if I could come up with a solution so end users around the world would not have to work so hard to edit a record in a long DataGrid.

I want to say one thing before I begin...it should be very rare that anyone has this problem because no on should be returning 100s of rows to a user. 99.9% of the time the user will not look at even a quarter of the rows returned (if you return 100s of rows). So, my advice too many of you that are having problems with scrolling, etc. is to build a better drill down interface. That said, there are times (users running at really low resolution, large text, etc.) where even 30 rows scrolls off the screen. I will now step off my soapbox.

Ok, let's look at the HTML/ASPX markup in our .aspx file (below).

<html>
..... Extraneous code removed .....

  <asp:DataGrid id=DataGrid1 runat="server">

	<Columns>
		<asp:EditCommandColumn ButtonType="LinkButton" 
				       UpdateText="Update" 
				       CancelText="Cancel" 
				       EditText="Edit">
		</asp:EditCommandColumn>
	</Columns>

  </asp:DataGrid>

..... Extraneous code removed .....
</html>
As you can see, there isn't much to dissect in the HTML/ASPX code (above). We have a standard DataGrid with an EditCommandColumn. The AutoGenerateColumns property is 'true' by default so the underlying data source will supply us with the rest of the columns in the DataGrid. I included this code here just show that there is nothing special going on in the .aspx file. Lets turn to the code in the code behind file (don't understand code behind - check out Steve Smith's article).

We will look at the two pieces of code that make the DataGrid auto-scroll. The first bit of code (below) is the Page_Load event.

Private Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) _
							Handles MyBase.Load

  If Not Page.IsPostBack Then
    'Only fill and bind the grid in the Page_Load event
    'CreateDataSource programmatically creates a DataTable
    DataGrid1.DataSource = CreateDataSource()
    DataGrid1.DataBind()
  Else
    Dim startUpScript As String
    startUpScript = "<script language=Javascript>location.href='#" _
			& Request.Form("__EVENTTARGET") & "';</script>"

    Me.RegisterStartupScript(Me.UniqueID & "StartUp", startUpScript)
  End If

End Sub
When the page first loads (Page.IsPostBack equals false), we want to fill the DataGrid with data and call the DataGrid's 'DataBind' method. If the page has been posted back to the server (i.e. the 'Edit', 'Update', or 'Cancel link is clicked), we want to emit some client-side script at the bottom of the page. The client-side script needs to be emitted at the bottom of the page so that it is executed after all of the controls have been emitted to the page.

The System.Web.UI.Page class contains a method called RegisterStartupScript for doing just that; emitting client-side script to be executed after the page loads. The RegisterStartupScript method takes two parameters - a 'key' of type string and a 'script' of type string. The key is a unique identifier that allows the Page to ensure that our script is only emitted to the page once. I usually only register one string of start up script so I use the UniqueID property of the Page class and concatenate it with the text 'StartUp'.

The 'script' parameter, as you probably could guess, is what is emitted to the page. In our case, we want to execute some Javascript that will send the user to a particular location on the page. We will make use of a named anchor tag (you will see how the anchor tag is created and emitted to the page later in the article) to achieve this functionality. The ASP.NET postback mechanism makes use of Javascript and anytime a postback capable control is emitted to the page, so is the Javascript to make the postback "Work". Here is the postback Javascript emitted by the ASP.NET postback mechanism:

<script language="javascript">
<!--
	function __doPostBack(eventTarget, eventArgument) {
		var theform = document.Form1;
		theform.__EVENTTARGET.value = eventTarget;
		theform.__EVENTARGUMENT.value = eventArgument;
		theform.submit();
	}
// -->
</script>
Looking at the Javascript, we can see that there is a single function (__doPostBack) that takes two arguments. The first argument (eventTarget) is the UniqueID if the control that caused the post back. The second argument (eventArgument) is an object that may contain additional values specific to the postback. Looking back at the code in the Page_Load event (shown a little earlier in the article), we can see that the code access the __EVENTTARGET element of the Request.Form collection. As mentioned earlier, the __EVENTTARGET element contains the UniqueID of the control that caused the post back to the server. We will use the UniqueID to name the anchor tag for each row in the DataGrid. Let's take a look at how we add name an anchor tag for each row in the DataGrid.

Private Sub DataGrid1_ItemDataBound(ByVal sender As Object, ByVal e As DataGridItemEventArgs) _
								Handles DataGrid1.ItemDataBound

  Select Case e.Item.ItemType
    Case ListItemType.Item, ListItemType.AlternatingItem
      Dim editButton As LinkButton = New LinkButton()
      editButton = CType(e.Item.Cells(0).Controls(0), LinkButton)
      editButton.Attributes.Add("name", "#" & editButton.UniqueID)

    Case ListItemType.EditItem
      Dim UpdateButton As LinkButton = New LinkButton()
      UpdateButton = CType(e.Item.Cells(0).Controls(0), LinkButton)
      UpdateButton.Attributes.Add("name", "#" & UpdateButton.UniqueID)
    End Select

End Sub

In our example, we don't have to create the anchor tag because our EditCommandColumn is using the LinkButton button type. If we were using the PushButton button type then we would need to actually add an anchor tag to each row. So, the EditCommandColumn is creating the anchor tag for us but we still need to add a name to the anchor tag so that our Javascript can send the page to it. To add the name attribute to the anchor tag for each row, we need to participate in the ItemDataBound event of the DataGrid. In the ItemDataBound event, we examine the ItemType property of each item. If the ItemType is of the type Item or AlternatingItem then we will add an attribute (name) with a value of "#" concatenated to the UniqueID of the 'Edit' LinkButton. If the ItemType is of the type EditItem then we will add an attribute (name) with a value of "#" concatenated to the UniqueID of the 'Update' LinkButton.

Click here to see a live example!
Click here to see all of the code!

Hopefully, you have found this article helpful. If you have comments, suggestions, etc. then feel free to contact me via this page.

We have many great DataGrid article here at AspAlliance.com. Click here to read them.

Featured Sponsor

 


An exclusive Microsoft partner!
 
Return to Top
   Home       Contact Alex       Useful Links       About Alex       Other AspAlliance.com Articles     
Hosted by ORCS Web
Contact: alowe@aspalliance.com