Article
Beginning ASP.NET Using VB.NET - Chapter 14: ASP.NET Server Controls
7. For the row you have just added, press the Delete link to test this function out. Let's see how all of this works.
How It Works-- Using the EditItem Template
Let's first look at the controls. We start with the server form, and a label to be used for displaying any error messages that might occur:
<html>
<body>
<form runat="server">
<asp:Label id="ErrorMessage" runat="server" /><br/>
Next, we add a LinkButton which is used as the link that adds new rows to the data. You could use an ordinary button here, but I think this looks neater:
<asp:LinkButton OnClick="DEDR_Add" Text="Add new event"
runat="server"/><br/>
Now we start on the DataGrid. The first thing to note, is that we have set the AutoGenerateColumns attribute to false, telling the DataGrid not to generate any columns automatically. One of the great features of the DataGrid is that when you bind data to it, it cycles through the rows and columns of the data and generates the HTML table accordingly. In this example, we don't want that, as we want to create the columns ourself:
<asp:DataGrid id="EventData"
AutoGenerateColumns="false" width="100%" runat="server"
Also, on the DataGrid, are some command properties. The DataGrid understands the concept of editing data, and has some special properties that allow us to tell it which event procedures are to be run when a set command is selected. You'll see how these commands are defined a little later:
OnEditCommand="DEDR_Edit"
OnUpdateCommand="DEDR_Update"
OnCancelCommand="DEDR_Cancel"
OnDeleteCommand="DEDR_Delete">
Next, we define some style properties of the DataGrid object. We could have done this using the attributes of the grid itself, but I thought it would be worthwhile showing a different way to do it. For example, we could do this:
<asp:DataGrid id="EventData" HeaderStyle-ForeColor="White"
HeaderStyle-BackColor="DodgerBlue"/>
There's no difference in the way the two methods of declaring these attributes work, so you can pick a style that you prefer. All we are doing here is defining the style properties for the various templates (the Header, Item and AlternatingItem).
<HeaderStyle ForeColor="White" BackColor="DodgerBlue"
Font-Bold="true"/>
<ItemStyle BackColor="White"/>
<AlternatingItemStyle BackColor="Gainsboro"/>
Now comes the bit where we define our columns. Remember, that it's us that's defining them, not the grid. For each column we are going to use a TemplateColumn (this is just a column type that allows you to customize the layout of controls in the column), denoting that the column is to have a template applied. Earlier in the chapter you saw some code like this:
<asp:DataList id="DataList1" runat="server">
<FooterTemplate>
'Items to be affected by this template
</FooterTemplate>
<SeparatorTemplate>
'Items to be affected by this template
</SeparatorTemplate>
</asp:DataList>
This defined a template and then, within the template, the columns. The DataGrid works the other way round, defining the columns first, and then the templates within each column. This is sensible because the grid is inherently columnar. So, we have our first template column, with some text to be placed in the header:
<Columns>
<asp:TemplateColumn HeaderText="Event">
Now, for this new column, we define the templates, the first being the ItemTemplate, which just shows the data:
<ItemTemplate>
<%# Container.DataItem("ShortDesc") %>
</ItemTemplate>
The line in the template is an advanced form of data binding. You've seen how we use the DataSource property of a server control (such as a DataGrid or Repeater) to identify where the data comes from. When you are defining the columns yourself, you need to specify which fields in the data are shown. To do this we have to refer to the Container, since this is where the data is stored. In our case the Container is the DataSet that the grid is bound to. We use the DataItem collection to point to a specific item -- it's ShortDesc in the example above, but could be the name of any field. ASP.NET knows this is advanced databinding because we have surrounded the binding details with <%# %>. This is very similar to the <% %> ASP tags, but it's the # which is the important bit -- it's that that switches on the binding features.
The grid will automatically put the HTML table tags (the TR and TD tags) in for us, so all we have to do is output the data using the databinding syntax described above. For the EditItemTemplate, which comes into effect when we are editing this row, we need some way to type in text, so we use a TextBox. In this case, we set the Text property of the text box to contain the data that we showed in the ItemTempate:
<EditItemTemplate>
<asp:TextBox id="txtShortDesc" Size="25" Text='<%#
Container.DataItem("ShortDesc") %>' runat="server"/>
</EditItemTemplate> </asp:TemplateColumn>
So that's the definition of one column. It's a TemplateColumn with two templates: one for just displaying the data, and one for editing the data. The ItemTemplate is normally used, until the row is put into edit mode (you'll see how in a while). When this happens ASP.NET automatically displays the EditItemTemplate for the selected row.
The other columns are exactly the same as this, just getting their data from different columns in the data set. The final column is different however, as it's here that we have out edit links. Again, there are two templates. For the ItemTemplate we have a link to Edit and a link to Delete. When we are in edit mode (the EditItemTemplate) we want different buttons -- to Update and Cancel. I've again used LinkButtons as I think they look nicer in this sample, but you could easily use standard buttons:
<asp:TemplateColumn>
<ItemTemplate>
<asp:LinkButton CommandName="Edit" Text="Edit"
runat="server"/>
<asp:LinkButton CommandName="Delete" Text="Delete"
runat="server"/>
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton CommandName="Cancel" Text="Cancel"
runat="server"/>
<asp:LinkButton CommandName="Update" Text="Update"
runat="server"/>
</EditItemTemplate>
</asp:TemplateColumn>
The key thing about this is the CommandName property, which identifies which command this button is associated with. Remember how when we defined the grid we identified event procedures with commands – well it's these commands that we were defining the procedures for. So the button with CommandName="Edit" will call the event procedure defined by OnEditCommand="DEDR_Edit".
Now let's look at the code.