GridView, DetailsView, and SqlDataSource Interaction Part 2
This article will show you how you can use the GridView, DetailsView, and SQLDataSource controls together to create features in a web site. This will be a multipart article talking about the various facets of using these three articles together. The article will make use of the AdventureWorks database, so if you do not have that installed, you can download it freely from Microsoft's web site. In addition, this article assumes you have an understanding of the GridView, DetailsView, and SqlDataSource controls, and how they can interrelate on a basic scale. It is also helpful to understand the various parameters of the data source controls, and how they can automatically map to server controls, query string values, and other sources.
A gridview, when linked to a details view, can be shown in a modal form; what I mean by that is, it can be shown in a popup window, where the main form is grayed out and only this window appears. The easiest way to implement this is using the AJAX Control Toolkit. To set this up, create a gridview bound to a source. Upon selecting an item, the selected index changed event fires, the details view data source control linked to the SelectedValue property populates the details view, and the details view will show the item in the popup.
Linking a details view item to a selection in the grid view is well documented on the web and won’t be discussed here. The process to do the popup is a little more complex. To understand how it works, realize that a modal popup extender is linked to an object to popup (a panel in this case) and a target that invokes the popup (a button in this case). It is possible to show and hide the popup programmatically (on the server) through the Show and Hide methods. Either way it is invoked, the extender still requires a button to trigger the event. To get around this, I usually use a hidden button, and invoke the panel through the Show method.
To make all of this work asynchronously, it requires that the grid/details view be wrapped in an update panel. The content of the update panel is shown below:
To invoke the popup, tap into the selected index changed event as such:
The modal popup will show on screen, showing the details of the product. Clicking the close link works seamlessly because the modal popup links to an OK and a Cancel button, which the close button works like a cancel in this scenario. There is one drawback to this approach; it may not work correctly upon refreshing, which will popup the modal screen again. I've experienced that in one of my projects recently.
In addition, what about making a more detailed message in cases where you want to search for something and no results are found? There are many ways to handle this, but there are a few important notes you should know about first. If you have a gridview bound to a data source initially, and the data source is connected to a control (like a search text box), you may experience where the gridview binds to the data source without there being any text present and no rows are returned. This occurs by design, and there are ways to circumvent this premature query. One way is to tap into the Selecting event of the data source control. If no text has been entered into the search text box, the searched can be cancelled through e.Cancel = true. This stops the data query from taking place.
The reason this is important is that if you have an EmptyDataTemplate defined or EmptyDataText set, this will display when no rows are returned. For a search page, the page initially loads and no search text can be entered, so an empty text message like "no records found" will be displayed erroneously. The scenario above can prevent that; there is another approach you can use, which is to not set the DataSourceID in the HTML markup. Instead, you assign it in code-behind whenever you have relevant search results, with code such as below:
This way, the grid is not directly linked, and only searched at the proper time. However, what if you wanted to create a more personalized "not found" message? To do that, you can leverage the approach above, and use the EmptyDataText property. Before binding, set that property as shown below:
You would do this assignment before binding regardless, because that message shows itself appropriately. What about changing the display values of the data being displayed? For instance, maybe you want to change a boolean value from 1/0 or true/false to Yes/No, something a little more appropriate. In this case, you can override the RowCreated or RowDataBound event to change the value. If you want to change the value after the initial binding only, use RowDataBound, but use RowCreated to process the row data everytime. In this event, you can do something like the following, to format currency values to something more appropriate:
This will convert the data appropriately. Being that you have access to the Row or to the Cell, you can change colors, fonts, styling, append javascript, or append CSS styles as appropriate. In the example above, if the value is below a certain amount, it could be colored appropriately. These are some of the things that can be done rather easily with the gridview and data source controls.