ASP.NET – GridView Control Customize a GridView Control In this note you use a GridView control to build two different applications – a Product List application and a Category Maintenance application. The web forms for these two applications are shown below. Source: Dr. Douglas Bock’s ASP.NET Programming How a GridView Control Works A GridView control displays data that is retrieved from a data source using a tabular row/column format. Advanced features: automatic (custom) paging, sorting, and customized appearance and behavior. Data is displayed in the control rendered as a HTML table, one row (Tr element) per data row. In the Category Maintenance web form shown above, the GridView control has five columns – three display data from the fields of theCategory table in the Halloween database – the last two display controls used to Edit or Delete existing rows in the table. o Clicking Edit causes the Edit button to disappear and a pair of Update and Cancel buttons appear. o Clicking Update saves data modifications (Edit reappears). o Clicking Cancel cancels data modifications (Edit reappears). The GridView control is found in the Toolbox, Data group. Use the smart tag arrow to bind the GridView to a data source with the Choose Data Source option. The basic GridView control properties (attributes) are given in this table: Property Description ID Control's ID Runat Must be set = "server" DataSourceID The ID of the data source to which the GridView is bound. DataKeyNames Primary Key field(s) – separate by commas for a composite primary key. AutoGenerateColumns Specifies to generate control columns automatically. SelectedIndex Row to be initially selected. Define GridView Control Fields A GridView displays one column in the table for each field (column) in a data source row. The Fields dialog box can be used to modify the columns displayed. Click the GridView control's smart arrow tag and select Edit Columns from the menu. You can add fields from the available fields and remove fields from those selected. Select a field in the Selected fields pane to modify BoundField properties. Columns for the control are defined by BoundField elements coded within a Columns element. Source: Dr. Douglas Bock’s ASP.NET Programming Columns can be added by choosing the Add New Columns option from a GridView smart tag menu or from the Fields dialog box. The common field properties are given in this table: Property Description DataField Name of data source column to which the field should be bound. DataFormatString A string format used to format data – e.g., {0:c} formats decimal values as currency. HtmlEncode Specifies if values are to be HTML-encoded prior to being displayed in a field. Set = False when theDataFormatString property is set. ItemStyle.Width Field width. ReadOnly Set = True if data will only be displayed; otherwise set = False. NullDisplayText Text to display if a data field is Null. ConvertEmptyStringtoNull Set = True if empty strings are treated as Null; Set = False if the database field does not allow Nulls. HeaderText Text to display as the header of the field. ShowHeader Set = True if the header is to be displayed for a field. Create and Format Fields A GridView control uses different child elements to create and format fields. Columns element – defines a collection of columns to display on a GridView. Between the Columns element's start and end tags you can place any combination of additional child elements. These include: o asp:BoundField – field bound to a data source column. o asp:ButtonField – field displays a Button control. o asp:CheckBoxField – field displays a CheckBox control. Source: Dr. Douglas Bock’s ASP.NET Programming o asp:CommandField – field contains either a Select, Edit, Delete, Update, or Cancel button. o asp:HyperlinkField – field displays a hyperlink. o asp:ImageField – field displays an image. o asp:TemplateField – field lets you create a column with custom content. A number of Style elements are used to format the display of data in the GridView. Use these instead of a CSS. o These include RowStyle, AlternatingRowStyle, SelectedRowStyle, EditRowStyle, ItemStyl e, HeaderStyle, and others. o All of these can be created automatically through use of the Fields dialog box discussed earlier, or by using AutoFormat (see the figure below for the smart arrow popup GridView Tasks dialog box). DateFormatString property – use this property to format fields containing numbers and dates. o A format string of {0:c} formats as currency. o You must set HtmlEncode property = False for the formatting to be applied. Enable Sorting A GridView control has a built-in ability to allow sorting of data rows based on any or all of the columns. To allow sorting: Use the Properties window – set AllowSorting = True (or use the Enable Sorting checkbox shown above in the GridView Tasks dialog box). Specify a SortExpression attribute for each column(s) for which sorting is to be allowed – since these expressions are generated automatically, you don't have to specify them; rather, you must delete those for columns for which you don't want to allow sorting (you can delete them in the HTML source code editor – sample code for the ProductID data field is shown below). Source: Dr. Douglas Bock’s ASP.NET Programming <asp:BoundField DataField="ProductID" HeaderText="Product ID" ReadOnly="True" SortExpression="ProductID"> <ItemStyle Width="100px" /> <HeaderStyle HorizontalAlign="Left" Width="100px" /> </asp:BoundField> The underlying data source must do the actual sorting so it must have its DataSourceMode = DataSet mode. To sort by two fields, for example by Name within CategoryID, specify a SortExpression attribute in the aspx coding window with two fields separated by a comma, e.g.: CategoryID, Name as shown below. <asp:BoundField DataField="CategoryID" HeaderText="Category" SortExpression="CategoryID, Name"> <ItemStyle Width="100px" /> <HeaderStyle Width="100px" /> </asp:BoundField> Enable Paging – Customize Paging Paging is the ability to display bound data one page at a time. To enable paging, access any column of the GridView control: Set AllowPaging = True (or check the Enable Paging checkbox in the GridView Tasks dialog box. Set PageSize = number of rows to display on each page – the default is 10 rows. A row will display at the bottom of the page that list the page numbers available through the control. Add a PagerStyle element (use the PagerStyle property of the control in the Properties window) to customize the appearance of pager controls. The underlying data source must be DataSet mode. The pager area can be customized with the PagerSettings element. The attribute used most often is Mode. Possible Mode settings are: NextPrevious – displays Next and Previous page buttons. Source: Dr. Douglas Bock’s ASP.NET Programming NextPreviousFirstLast – displays Next, Previous, First, and Last buttons. Numeric – displays page numbers. NumericFirstLast – displays First and Last buttons along with page numbers if the number of pages exceeds the value specified in thePageButtonCount attribute. <PagerStyle Mode="NumericFirstLast" BackColor="#284775" ForeColor="White" HorizontalAlign="Center" BorderColor="#0000CC" /> Other PagerSettings element attributes enable displaying images instead of buttons or text on buttons or the location of the pager area (use thePosition attribute). Product List Application Designing the Product List Application Begin a new web project named Ch14ProductList. Select the project node and use the Website menu to add a new item – select the web form template – name the web formProductListGridView.aspx. Create a folder named Images – add a copy of the banner.jpg file to the folder. Add an Image control to the web form. Set ImageUrl = ~Images/banner.jpg (use the Select Image dialog box). Space down two lines and add a GridView control from the Toolbox, Data group. Add a SqlDataSource control. Configure the control as follows: o Click the control’s smart arrow tag and select the Configure Data Source option. o Connect to the Halloween.mdf database on CMIS3 (you may use an existing connection or create a new one) – if you are working from home, you may elect to add the database to the App_Data folder and connect to the database locally. o Save the connection string as HalloweenConnectionString. o In the Configure Select Statement window, select the Products table and the columns shown in the figure given below. Source: Dr. Douglas Bock’s ASP.NET Programming o Order by the ProductID columns. o Click Next and test the query. o Click Finish to dismiss the dialog box. Now bind the GridView control to the SqlDataSource control. Select the GridView control's smart tag arrow and set the data source with the Choose Data Source option to the SqlDataSource1 object. In the smart tag arrow menu: o Select AutoFormat and in the Auto Format dialog box select the Professional setting as shown in the figure below – click OK to continue work. o In the GridView Tasks dialog box shown in the figure below check the Enable Paging and Enable Sorting checkboxes. Source: Dr. Douglas Bock’s ASP.NET Programming o Click the Edit Columns option. Edit each column's property values as specified in this table by selecting the columns one at a time from the Selected Fields pane of the Fields dialog box – CAUTION: Do not mistakenly change the DataField property setting or you will lose binding for the column to the database. o Also set UnitPrice's DataFormatString = {0:c} and HtmlEncode = False to format the UnitPrice as currency. Column HeaderText ItemStyle & HeaderStyle – Width ItemStyle & HeaderStyle – HorizontalAlign Sort Expression ProductID Product ID 100px Left ProductID Name Product Name 200px Not Set Name CategoryID Category 80px Not Set CategoryID UnitPrice Price 100px Right <blank> OnHand Quantity 100px Right <blank> Click OK to exit the Fields dialog box. Use the Properties window and set the GridView's PagerSettings property, Mode option = NumericFirstLast to format the pager area. Run the project and test the layout and display of data. Save the project. Run the project and inspect the layout for appropriate column sizes, alignment, and formatting. Confirm the appropriate columns will sort the display. Confirm the paging works. Source: Dr. Douglas Bock’s ASP.NET Programming Product List Application ASPX Code No VB code-behind file is needed. This listing shows the ASPX code for the application. Pick out the following elements and attributes: Columns element with five BoundField child elements. SortExpression attribute for the first three fields. DataFormatString and HtmlEncode for the fourth field. PagerStyle element and PagerSettings element. The SelectCommand attribute of the SqlDataSource element. <%@ Page Language="VB" AutoEventWireup="false" CodeFile="ProductListGridVi ew.aspx.vb" Inherits="ProductListGridView" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:Image ID="Image1" runat="server" ImageUrl="~/Images/banner.jp g" /> <br /> <br /> <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" CellPadding="4 " DataKeyNames="ProductID" DataSourceID="SqlDataSource1" ForeCol or="#333333" GridLines="None"> <AlternatingRowStyle BackColor="White" ForeColor="#284775" /> <Columns> <asp:BoundField DataField="ProductID" HeaderText="Product ID" ReadOnly="True" SortExpression="ProductID"> <HeaderStyle HorizontalAlign="Left" Width="100px" /> <ItemStyle HorizontalAlign="Left" Width="100px" /> </asp:BoundField> <asp:BoundField DataField="Name" HeaderText="Product Name" SortExpression="Name"> <HeaderStyle Width="200px" /> <ItemStyle Width="200px" /> </asp:BoundField> <asp:BoundField DataField="CategoryID" HeaderText="Categor y" Source: Dr. Douglas Bock’s ASP.NET Programming SortExpression="CategoryID"> <HeaderStyle Width="80px" /> <ItemStyle Width="80px" /> </asp:BoundField> <asp:BoundField DataField="UnitPrice" DataFormatString="{0 :c}" HeaderText="Price" HtmlEncode="False"> <HeaderStyle HorizontalAlign="Right" Width="100px" /> <ItemStyle HorizontalAlign="Right" Width="100px" /> </asp:BoundField> <asp:BoundField DataField="OnHand" HeaderText="Quantity"> <HeaderStyle HorizontalAlign="Right" Width="100px" /> <ItemStyle HorizontalAlign="Right" Width="100px" /> </asp:BoundField> </Columns> <EditRowStyle BackColor="#999999" /> <FooterStyle BackColor="#5D7B9D" FontBold="True" ForeColor="White" /> <HeaderStyle BackColor="#5D7B9D" FontBold="True" ForeColor="White" /> <PagerSettings Mode="NumericFirstLast" /> <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAl ign="Center" /> <RowStyle BackColor="#F7F6F3" ForeColor="#333333" /> <SelectedRowStyle BackColor="#E2DED6" FontBold="True" ForeColor="#333333" /> <SortedAscendingCellStyle BackColor="#E9E7E2" /> <SortedAscendingHeaderStyle BackColor="#506C8C" /> <SortedDescendingCellStyle BackColor="#FFFDF8" /> <SortedDescendingHeaderStyle BackColor="#6F8DAE" /> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:HalloweenConnectionStr ing %>" SelectCommand="SELECT [ProductID], [Name], [CategoryID], [UnitPrice], [OnHand] FROM [Products] ORDER BY [ProductID]"> </asp:SqlDataSource> <br /> </div> </form> </body> </html> Update GridView Data A GridView control can be used to update data for its data source. The data source must be configured for SQL Update, Delete, and Insertstatements. Source: Dr. Douglas Bock’s ASP.NET Programming Command Fields A Command Field is a GridView column with one or more button controls that enable an application user to cancel, delete, edit, select, and update data for a specific data row. A CommandField has an insert button capability, but the GridView control does not directly support a SQL insert operation. The properties and settings and capabilities generally set or uses include: Set ButtonType = the type of button to display (Button, Link, or Image). Set the Button property = the action the button is to display (Cancel, Delete, Edit, Select, or Update). The text and image values displayed on a button are set with appropriate properties, e.g., CancelText or CancelImage for the Cancel button,DeleteText or DeleteImage for the Delete button, and so forth. Edit button – clicking this button places the selected GridView control row in edit mode. o Labels displaying data are automatically replaced by TextBox controls so that data can be modified. o The Edit button is automatically replaced by Update and Cancel buttons. o The Update button sends changes back to the data source which then updates the database. o The Cancel button discards any changes and restores original values. Select button – allows an application user to select a row. o SelectedIndex and SelectedRow properties update automatically to reflect the selected row. o This capability will be explored more in a later module. Delete button – an application user clicks this button to delete a row. o The GridView control automatically calls the data source's Delete method. o The row is deleted from the data source and then the database. o The GridView control automatically redisplays the data from the data source without the deleted row. You should create separate command fields for Select, Edit, and Delete buttons. For Select and Delete: set CausesValidation = False so they do not trigger any validation. For Edit: set CausesValidation = True so data is validated when Update is clicked. GridView Control Events A GridView control can raise various events. Code these events as necessary to: validate data. handle database exceptions. handle concurrency errors. Source: Dr. Douglas Bock’s ASP.NET Programming Some events are termed before-action and occur just before a specific action such as the RowDeleting event (a row is about to be deleted). Other events are after-action events such as the RowDeleted event (a row has been deleted). Before-action events:– o Use these primarily to handle special data validation. o To cancel an Update or Delete, set e.Cancel = True in program code. After-action events – use to ensure a database operation completed successfully. You will usually test for two conditions as shown in the coding example given below: o Check the e.Exception property (of the e argument) to determine if a database exception occurred. o Check for a concurrency violation by testing the e.AffectedRows property – if it equals zero, no rows were changed and a concurrency error probably occurred. Protected Sub GridView1_RowUpdated(ByVal sender As Object, ByVal e AsSyste m.Web.UI.WebControls.GridViewUpdatedEventArgs) Handles GridView1.RowUpdate d 'Test for an error during processing If e.Exception IsNot Nothing Then 'Test for an exception during row update lblError.Text = "An error occurred. " & e.Exception.Message 'This suppresses the exception and keeps the 'row in EditMode e.ExceptionHandled = True e.KeepInEditMode = True ElseIf e.AffectedRows = 0 Then 'Test for a concurrency error 'If e.AffectedRows is zero, then no rows updated lblError.Text = "No rows were updated. Another user may have updated that category. Please try again." Else lblError.Text = "Update succeeded." End If End Sub The events you may need to code are described in this table: Event RowCancelingEdit RowDataBound RowDeleted RowDeleting RowEditing RowUpdated RowUpdating Source: Dr. Douglas Bock’s ASP.NET Programming Description Cancel button of row in edit mode is clicked. Data binding completes for a row. Row has been deleted. Row about to be deleted. Row is about to be edited. Row has been updated. Row is about to be updated. SelectedIndexChanged SelectedIndexChanging Row has been selected. Row is about to be selected. Insert a Row in a GridView Control A GridView control does not support Insert operations except when used with a FormView or DetailsView controls – covered in Module 15. In this project, row insertions are handled by creating a set of input controls (usually TextBox controls) for data entry and by providing a Buttoncontrol to click to insert a row. A data source's Insert method is used to add a row. The Button's Click event must use parameter values to store data to be inserted in the row. Exception handling must be coded—the most likely exception is a Primary Key Constraint violation—trying to insert a row with a primary key value that duplicates one in an existing database row. In this next coding example, the SqlDataSource control is named dsCategory. Three parameters are created, one for each column in the Categories table, and the parameter's DefaultValue property is assigned the value of the associated TextBox control's Text property. The Insert method is used to insert a row and the TextBoxes are cleared. The Catch block displays an exception message of the Insert method fails. Protected Sub btnAdd_Click(ByVal sender As Object, ByVal e As System.Event Args) Handles btnAdd.Click Try 'Store values to parameters from TextBox controls – if necessary 'convert the data type from string (textbox) to the data type for the 'column in the database table dsCategory.InsertParameters("CategoryID").DefaultValue = txtID.Text dsCategory.InsertParameters("ShortName").DefaultValue = txtShortName.Text dsCategory.InsertParameters("LongName").DefaultValue = txtLongName.Text 'Use Insert method to insert a row dsCategory.Insert() 'Clear the TextBox controls txtID.Text = "" txtShortName.Text = "" txtLongName.Text = "" lblError.Text = "Add succeeded." Catch ex As Exception Source: Dr. Douglas Bock’s ASP.NET Programming 'Display exception message if the Insert fails lblError.Text = "An error occurred. " & ex.Message End Try End Sub Category Maintenance Application In this section of notes, you will build an application that uses a GridView control to enable the maintenance of data stored in the Categoriesdatabase table. Data maintenance involves adding new records, editing existing records, and deleting records for a database. Designing the Category Maintenance Application Begin a new web project named Ch14CategoryMaintenance. Select the project node and use the Website menu to add a new item – select the web form template – name the web formCategoryMaintGridView.aspx. Create a folder named Images – add a copy of the banner.jpg file to the folder. Add an Image control to the web form. Set ImageUrl = ~/Images/banner.jpg (use the Select Image dialog box). Space down two lines. Add text to read Category Maintenance (18 point-Bold print – just below the Image control). Your form now looks like the one shown in this figure. Add a GridView control from the Toolbox, Data group below the Category Maintenance text. Add a SqlDataSource control. Configure the control as follows: o Set ID = dsCategory. o Click the control’s smart arrow tag and select the Configure Data Source option. o Connect to the Halloween.mdf database on CMIS3 (you may use an existing connection or create a new one) – if you are working from home, you may elect to add the database to the App_Data folder and connect to the database locally. o Save the connection string as HalloweenConnectionString. o In the Configure the Select Statement select the radio button to Specify a custom SQL statement or stored procedure as shown in this figure. Click Next. Source: Dr. Douglas Bock’s ASP.NET Programming o In the Define Custom Statements or Stored Procedures window type the Select statement (shown below) or use the Query Builderto generate the Select statement for the SELECT tab as shown in this figure. The square brackets are generated by the Query Builder but are only necessary whenever a column or table name contains embedded blank spaces. SELECT [CategoryID], [ShortName], [LongName] FROM [Categories] o For the UPDATE tab enter the Update statement shown here or use the Query Builder. The Query Builder window for the Update statement looks like this figure. UPDATE [Categories] SET [ShortName] = @ShortName, [LongName] = @LongName WHERE [CategoryID] = @original_CategoryID AND [ShortName] = @original_ShortName Source: Dr. Douglas Bock’s ASP.NET Programming AND [LongName] = @original_LongName The @original_<ColumnName> parameters are used for optimistic concurrency control – if the original values have changed since the data was retrieved by an application user, then an Update transaction will fail. The @ShortName and @LongName parameters will store the values to be saved to the ShortName and LongName columns of the Categoriestable to modify an existing row. The CategoryID column is not allowed to be changed because it is a primary key. o For the INSERT tab enter the Insert statement shown here or use the Query Builder. The Query Builder is shown in this figure. INSERT INTO [Categories] ([CategoryID], [ShortName], [LongName]) VALUES (@CategoryID, @ShortName, @LongName) Source: Dr. Douglas Bock’s ASP.NET Programming The @CategoryID, @ShortName and @LongName parameters will store the values to be saved to the CategoryID, ShortName and LongNamecolumns of the Categories table for a new record (row). o For the DELETE tab enter the Delete statement shown here. DELETE FROM [Categories] WHERE [CategoryID] = @original_CategoryID AND [ShortName] = @original_ShortName AND [LongName] = @original_LongName Source: Dr. Douglas Bock’s ASP.NET Programming As with the Update statement, the parameters used in the Delete statement are to check the original values in a column(s) to be deleted is to enforce optimistic concurrency checking. Test the Select query if desired. Click Next, then click the Test Query button to test the query. The four rows from the Categories table should be retrieved. Click Finish to complete configuring the SqlDataSource object. IMPORTANT: Two additional properties of the SqlDataSource control need to be checked and set if necessary: o ConflictDetection = CompareAllValues – this means optimistic concurrency checking will be done. o OldValuesParameterFormatSource = original_{0} (that's the word original + an underscore + braces with zero in the middle – this setting should be the default to mean the name of each original parameter will include the column name prefixed with the word "original_". Select the GridView control's smart tag arrow – set Choose Data Source = dsCategory. The form now looks like the following figure. Source: Dr. Douglas Bock’s ASP.NET Programming Inserting Command Field Columns The GridView control needs two Command Field columns to display command buttons used to Edit and Delete rows. Click the GridView control's smart tag arrow – select Add New Column to add a column of Edit buttons. In the Add Field dialog box (see figure below): o Select CommandField from the Choose a field type drop-down. o Leave Header text blank. o Select Button from the Button type drop down. o Check the Edit/Update checkbox and Show cancel button checkbox. o Click OK. Source: Dr. Douglas Bock’s ASP.NET Programming Click the GridView control's smart tag arrow – again select Add New Column to add a column of Delete buttons. In the Add Field dialog box (see figure below): o Select CommandField from the Choose a field type drop-down. o Leave Header text blank. o Select Button from the Button type drop down. o Check the Delete checkbox. Set the CausesValidation property to False for the two Edit, Update, Cancel and the Delete button columns by selecting the Columns (collection) property of the GridView control to display the Fields dialog box. o Select the Delete field as shown in this figure and set CausesValidation = False. o Repeat this for the Edit, Update, Cancel field as shown in this figure. Source: Dr. Douglas Bock’s ASP.NET Programming Note: Normally the CausesValidation property is left at True for the Edit button column of a Command Field, but we are setting it to False. The web form now looks approximately like that shown in this figure. Source: Dr. Douglas Bock’s ASP.NET Programming Test the application just to examine how the form looks. The functionality will be tested after the ASP.Net code is added to the code-behind file. Completing the Design Layout Complete the design layout to support inserting new data records. Add controls below the SqlDataSource object as shown in this figure. Add text that reads: Insert new categories by entering the information and clicking Add New Category. Access the Table Insert Table menu option and add a table with three columns and three rows that is about 550 pixels in total width. Add text as shown in the figure above in the table's first column. Add three TextBox and RequiredFieldValidator controls as shown in the figures second and third columns. Set the properties as follows: o TextBox1 – ID = txtID; Width = 100px. o TextBox2 – ID = txtShortName; Width = 160px. o TextBox3 – ID = txtLongName; Width = 275px. o RequiredFieldValidator1: ControlToValidate = txtID. ErrorMessage = Category ID is required. SetFocusOnError = True. o RequiredFieldValidator2: ControlToValidate = txtShortName. ErrorMessage = Short name is required. SetFocusOnError = True. o RequiredFieldValidator3: ControlToValidate = txtLongName. ErrorMessage = Long name is required. SetFocusOnError = True. Source: Dr. Douglas Bock’s ASP.NET Programming Add a Button control with property settings of: ID = btnAdd; CausesValidation = True; Text = Add New Category. Add a Label control named lblError . o Set ForeColor = Red to be used to display exception messages. o Set EnableViewState = False to cause the label to clear automatically when the form posts back. o Set Text = <blank>. Coding the Category Maintenance Application The btnAdd button's Click event sub procedure sets the values of three parameters required by the SQL Insert command that was generated earlier. These parameters are @CategoryID, @ShortName, and @LongName although the @ symbol is not used in the code shown here. The Try-Catch block contains a dsCategory.Insert command to call the Insert method of the DataSource control. If the insert works, the TextBox controls are cleared; otherwise, an exception message displays to a label used for the purpose. Protected Sub btnAdd_Click(ByVal sender As Object, ByVal e As System.Event Args) Handles btnAdd.Click Try 'Store values to parameters from TextBox controls – if necessary 'convert the data type from string (textbox) to the data type for the 'column in the database table dsCategory.InsertParameters("CategoryID").DefaultValue = txtID.Text dsCategory.InsertParameters("ShortName").DefaultValue = txtShortName.Text dsCategory.InsertParameters("LongName").DefaultValue = txtLongName.Text 'Use Insert method to insert a row dsCategory.Insert() 'Clear the TextBox and Label controls txtID.Text = "" txtShortName.Text = "" txtLongName.Text = "" lblError.Text = "Add succeeded." Catch ex As Exception 'Display exception message if the Insert fails lblError.Text = "An error occurred. " & ex.Message End Try End Sub The GridView1_RowUpdated event fires after a row is updated. Source: Dr. Douglas Bock’s ASP.NET Programming The e.Exception property (of the e argument) is tested to determine if an exception has been thrown – if it has, the exception is displayed. Setting e.ExceptionHandled to True handles the exception by suppressing it. Setting e.KeepInEditMode to True keeps the GridView control in edit mode. If no exception is thrown, the e.AffectedRows argument is checked to determine its value. If e.AffectedRows has a value of zero then it is likely that a concurrency error has occurred; otherwise, the Update executed satisfactorily. Protected Sub GridView1_RowUpdated(ByVal sender As Object, ByVal e As Syst em.Web.UI.WebControls.GridViewUpdatedEventArgs) Handles GridView1.RowUpdat ed 'Test for an error during processing If e.Exception IsNot Nothing Then 'Test for an exception during row update lblError.Text = "A database error occurred: " & e.Exception.Message 'This suppresses the exception and keeps the 'row in EditMode e.ExceptionHandled = True e.KeepInEditMode = True ElseIf e.AffectedRows = 0 Then 'Test for a concurrency error 'If e.AffectedRows is zero, then no rows updated lblError.Text = "No records were updated. Another user may have updated that category. Please try again." Else lblError.Text = "Update succeeded." End If End Sub The GridView1_RowDeleted event fires after a row has been deleted. As with the RowUpdated procedure, if e.Exception contains a value, then the exception is shown; otherwise, the e.AffectedRows value is checked to determine if a concurrency error occurred. The label can be coded as follows: 'Test for an exception during row deletion lblError.Text = "A database error occurred: " & e.Exception.Message Alternatively you can assume the error is due to a referential integrity error and code the label as follows: 'Test for an exception during row deletion lblError.Text = "Unable to delete the selected category – there are existing products for the category in the database." Source: Dr. Douglas Bock’s ASP.NET Programming Protected Sub GridView1_RowDeleted(ByVal sender As Object, ByVal e As Syst em.Web.UI.WebControls.GridViewDeletedEventArgs) Handles GridView1.RowDelet ed 'Test for an error during processing If e.Exception IsNot Nothing Then 'Test for an exception during row deletion lblError.Text = "Unable to delete the selected category – there are existing products for the category in the database." 'This suppresses the exception e.ExceptionHandled = True ElseIf e.AffectedRows = 0 Then 'Test for a concurrency error 'If e.AffectedRows is zero, then no rows deleted lblError.Text = "No records were deleted. Another user may have updated this category. Please try again." Else lblError.Text = "Delete succeeded." End If End Sub Test the application. You should be able to: Insert a new Category record. Modify an existing record. Delete the new record that was inserted. Deleting an existing record should cause an exception due to referential integrity to the Products table. Template Fields Using Template Fields in place of Bound Fields adds a degree of flexibility to a project. This adds the ability to use templates to render a column. It also adds the ability to use validation controls for each editable GridView control. Create Template Fields To create a template field, there are two approaches that can be used: Click the Smart Arrow Tag and selecting the Add New Column hyperlink to display the Add Fields dialog box - this enables adding an additional, new bound field as shown in this figure. Source: Dr. Douglas Bock’s ASP.NET Programming The other approach is to access the GridView control's Columns (collection) property to display the Fields dialog box - this enables modifying an existing bound field. Assume you are continuing with the above project so you already have bound fields that can be modified. Click the Convert This Field into a TemplateField link as shown in this figure. To edit a template, choose Edit Templates from the smart tag arrow – select the template to edit from the smart tag menu and add text and other controls such a validation controls. To quit choose End Template Editing in the smart tag menu. Source: Dr. Douglas Bock’s ASP.NET Programming Category Maintenance Template Version Each field that displays data from the Categories table in the GridView control needs to be converted to a Template Field. Additionally, theShortName and LongName fields need validation controls (RequiredFieldValidator) that are assigned to a specific validation group named Edit. Access the GridView control's Columns (collection) property in the Properties window.. In the Selected fields pane, select each field that displays data (the CategoryID, ShortName, and LongName) – click the Convert This Field into a TemplateField link. Click OK to dismiss the dialog box. In design view, right-click the CategoryID column and use the context menu to select the GridView control's smart tag arrow – select Edit Template. Select Column[0] – CategoryID – for the ItemTemplate and EditItemTemplate change the Label1 name to lblCategoryID as shown. Select Column[1] – ShortName – for the ItemTemplate change Label2 name to lblShortName. For the EditItemTemplate add aRequiredFieldValidator control next to the TextBox as shown here. o Set TextBox1 ID = txtShortName. o Set the RequiredFieldValidator control properties: ControlToValidate = txtShortName. ErrorMessage = Short name is required. ForeColor = Red. Text = *. ValidationGroup = Edit. Source: Dr. Douglas Bock’s ASP.NET Programming Select Column[2] – LongName – for the ItemTemplate change Label3 name to lblLongName. For the EditItemTemplate add aRequiredFieldValidator control next to the TextBox as you did above. o Set TextBox2 ID = txtLongName. o Set the RequiredFieldValidator control properties: ControlToValidate = txtLongName. ErrorMessage = Long name is required. ForeColor = Red. Text = *. ValidationGroup = Edit. Click the Smart Arrow Tag and click the End Template Editing hyperlink. The Edit buttons in the Edit button column need to cause validation of the form. Select the Edit button column as shown in this figure and click the GridView control's smart tag arrow and select Edit Columns. Source: Dr. Douglas Bock’s ASP.NET Programming In the Fields dialog box select the Edit, Update, and Cancel fields entry as shown in this figure – set the CausesValidation property toTrue. Set ValidationGroup = Edit. Click OK to dismiss the dialog box. A ValidationSummary control is needed to display validation error messages for the GridView control. Add a ValidationSummary control just below the GridView control. Source: Dr. Douglas Bock’s ASP.NET Programming Set HeaderText = Correct these errors. Set ValidationGroup = Edit. Set ForeColor = Red. Two different groups of validation controls must be used. The validation controls for the GridView control are assigned to the group named Edit. The validation controls for the table used to add a new category of products must be assigned to a group named New. Select the RequiredFieldValidator controls for the HTML table used to add a new category row and set ValidationGroup = New. Test the application. It should function without error. No changes to the form's VB code-behind file is necessary. At runtime, a web form with an error will display the ValidationSummary control - your form will look approximately like the one shown in this figure. Source: Dr. Douglas Bock’s ASP.NET Programming