ASP.NET DataList and DataRepeater Controls

This is the third article in a three part series of articles pertaining to the understanding and application of ASP.NET 2.0 data controls. This article will address common functionality that may be required from ASP.NET DataList and DataRepeater data controls.


ASP.NET 2.0 Data Controls

Author: Douglas Minnaar
The intent of this series is to provide more information concerning the functionality and limitations of the available ASP.NET 2.0 data controls. This will mostly be demonstrated through the use of code samples. Once this series is complete, I will demonstrate how one can AJAX enable some of these samples to improve the overall user experience. Therefore, this series will address the basics first before moving onto more advanced tools. Many will feel that there is enough information available concerning these matters. However, for completeness sake, I feel it is important to provide a good foundation from which to launch future articles from. The articles in this series will address typical scenarios that one might encounter in terms of developing with ASP.NET data controls.
There will be three parts in this series:
The SqlDataSource control is used throughout the series for simplicities sake.

Part 3 - ASP.NET DataList and Repeater control

This is the third article in a three part series of articles pertaining to the understanding and application of ASP.NET 2.0 data controls. This article will address common functionality that may be required from ASP.NET DataList and DataRepeater data controls.
Level: Novice - Intermediate
Prerequisites:
  • In order for the sample code to run, one will require the Northwind database running on either SqlExpress or Sql2005.
  • An understanding of C# and ASP.NET development code
Please download the code here

Introduction

Based on various Microsoft documentation, the ASP.NET DataList and Repeater can be summarised as follows.
The DataList control is a data bound list control that displays items using templates. Use the DataList control to display a template-defined data bound list. The DataList control supports selecting and editing. The contents of the DataList control can be manipulated by using templates. In my experience, I have found the DataList control to be useful and well suited to websites that have content focusing on the selling of products. One is able to build rich product catalogs with relative ease using the DataList control.
The Repeater control is a basic templated data-bound list. It has no built-in layout or styles, so you must explicitly declare all HTML layout, formatting, and style tags within the control's templates. The Repeater control is the only Web control that allows a developer to split HTML tags across the templates. To create a table using templates, include the begin table tag (<table>) in the HeaderTemplate, a single table row tag (<tr>) in the ItemTemplate, and the end table tag (</table>) in the FooterTemplate. The Repeater control has no built-in selection capabilities or editing support. The user can use the ItemCommand event to process control events that are raised from the templates to the control. In my experience, as with the DataList control, I have found the Repeater control useful and well suited to implementing product catalogs. I have also used the Repeater control to produce a very simple lightweight reporting solution.
I have not mentioned this before in any of the previous articles, but it should be noted that ASP.NET server controls such as the Repeater, DataList and GridView Web controls can contain child controls that raise events. Therefore, a DataList control may have a child control as part of a template that raises an event. The child control event is "bubbled up " (sent up) to the control's container. The container control raises an event called RowCommand with parameter values. These values allow one to determine which control raised the original event. One is then able to respond to this event. Alternatively, one can write individual event handlers for the child controls.
Furthermore the following should be noted about the DataList and Repeater control:
  • Using the DataSourceID property, binding to data source controls, such as SqlDataSource, ObjectDataSource, and XmlDataSource, is supported
  • Using the DataSource property, binding to an object that implements the System.Collections.IEnumerable interface is supported
  • DataList supports selecting and editing. Typically, the Repeater is mostly used for displaying data records. However, because of event bubbling, one is able to implement more advanced behaviour within a Repeater control.

Example Details

For this example, a DataList control is used to display a list of customers similar to a contact list. The customers will be displayed in a template that resembles a business card. One is able to view a quick report of orders for a selected customer. The order report will be displayed in a simple Repeater control. A SqlDataSource is used to retrieve data from the database. The DataList allows one to edit existing customers as well as view more detailed information concerning a customer. Something similar to a master detail scenario has been setup such that the DataList behaves as the master and the Repeater control as the detail. However, the Repeater will not display detail concerning the customer but instead a list of orders. The DataList passes a unique id to a modal dialog that contains the Repeater. The repeater will then load a list of orders based on the unique id it recieves.
We will be using the SqlDataSource as a data provider in this example. The example will demonstrate the following features:
  • Bind DataList to a SqlDataSource (It should be noted that I only use the SqlDataSource for demonstration purposes. I favour the ObjectDataSource over the SqlDataSource in terms of the development I have been involved in)
  • Search data using a query statement, ASP.NET control parameters, and ASP.NET controls (TextBox and DropDownList) as the input.
  • Edit/Update behaviour with the ASP.NET RequiredFieldValidator.
  • Select behaviour.
  • How to determine selected items in a DataList control.
  • Master/Details using a modal dialog.
  • Use the DataList cancel, edit, item and update command events.
  • Bind Repeater control to SqlDataSource based on a QueryString parameter.
  • A simple demonstration as to how one would use a custom method with a Repeater that formats a date.
  • Change the way the output is rendered in terms of columns and orientation
Note: Please refer to the solution code concerning the following scenarios.
Bind DataList to a SqlDataSource
For this example, a SqlDataSource is used for the DataList data source. The DataList DataSourceID is set to the id of the SqlDataSource.
The following code snippet illustrates the setup required in terms of the DataList control.
We will explore the use of the OnEditCommand, OnCancelCommand, OnUpdateCommand and OnItemCommand later in the article. The important thing to note is that we are using a DataSourceID because we are binding to a SqlDataSource. By default, the items will display accross three columns. CustomerId is used as the primary key or DataKeyField.
<asp:DataList ID="CustomerDataList"
  runat="server" DataSourceID="CustomerSqlDataSource"
  RepeatColumns="3" DataKeyField="CustomerID"
  OnEditCommand="CustomerDataList_EditCommand"
  OnCancelCommand="CustomerDataList_CancelCommand"
  OnUpdateCommand="CustomerDataList_UpdateCommand"
  OnItemCommand="CustomerDataList_ItemCommand">
  <EditItemTemplate>
    <table>
      <tr>
        <td colspan="2" style="font-size: 10px">
          &nbsp;</td>
      </tr>
      <tr>
        <td style="width: 5px;
          background-color: #4682B4">
          <asp:Panel ID="SidePanel"
            Width="5px" runat="server" />
        </td>
        <td>
          <asp:Panel ID="CustomerPanel"
            runat="server" CssClass="CustomerPanel">
            <table>
              <tr>
                <td style="width: 50px">
                </td>
                <td style="width: 5px">
                </td>
                <td style="width: 235px">
                </td>
              </tr>
              <tr>
                <th align="right">
                  Company Name:</th>
                <td>
                </td>
                <td>
                  <asp:TextBox ID="CompanyNameTextBox"
                    runat="server" Text='<%# Bind("CompanyName") %>' />
                  &nbsp;<asp:RequiredFieldValidator
                    ID="CompanyRfv" runat="server"
                    ControlToValidate="CompanyNameTextBox"
                    ErrorMessage="*" ToolTip="Company name is required"
                    ValidationGroup="UpdateCustomerVG" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Contact:</th>
                <td>
                </td>
                <td>
                  <asp:TextBox ID="ContactNameTextBox"
                    runat="server" Text='<%# Bind("ContactName") %>' />
                  &nbsp;<asp:RequiredFieldValidator
                    ID="ContactNameRfv"
                    runat="server" ControlToValidate="ContactNameTextBox"
                    ErrorMessage="*" ToolTip="Contact name is required"
                    ValidationGroup="UpdateCustomerVG" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Title:</th>
                <td>
                </td>
                <td>
                  <asp:TextBox ID="ContactTitleTextBox"
                    runat="server" Text='<%# Bind("ContactTitle") %>' />
                  &nbsp;<asp:RequiredFieldValidator
                    ID="ContactTitleRfv"
                    runat="server" ControlToValidate="ContactTitleTextBox"
                    ErrorMessage="*" ToolTip="Contact title is required"
                    ValidationGroup="UpdateCustomerVG" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Phone:</th>
                <td>
                </td>
                <td>
                  <asp:TextBox ID="PhoneTextBox"
                    runat="server" Text='<%# Bind("Phone") %>' />
                  &nbsp;<asp:RequiredFieldValidator
                    ID="PhoneTextBoxRfv"
                    runat="server" ControlToValidate="PhoneTextBox"
                    ErrorMessage="*" ToolTip="Phone number is required"
                    ValidationGroup="UpdateCustomerVG" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Fax:</th>
                <td>
                </td>
                <td>
                  <asp:TextBox ID="FaxTextBox"
                    runat="server" Text='<%# Bind("Fax") %>' />
                  &nbsp;<asp:RequiredFieldValidator
                    ID="FaxRfv" runat="server"
                    ControlToValidate="FaxTextBox"
                    ErrorMessage="*" ToolTip="Fax number is required"
                    ValidationGroup="UpdateCustomerVG" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Address:</th>
                <td>
                </td>
                <td>
                  <asp:TextBox ID="AddressTextBox"
                    runat="server" Text='<%# Bind("Address") %>' />
                  &nbsp;<asp:RequiredFieldValidator
                    ID="AddressRfv" runat="server"
                    ControlToValidate="AddressTextBox"
                    ErrorMessage="*" ToolTip="Address is required"
                    ValidationGroup="UpdateCustomerVG" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  City:</th>
                <td>
                </td>
                <td>
                  <asp:TextBox ID="CityTextBox"
                    runat="server" Text='<%# Bind("City") %>' />
                  &nbsp;<asp:RequiredFieldValidator
                    ID="CityRfv" runat="server"
                    ControlToValidate="CityTextBox"
                    ErrorMessage="*" ToolTip="City is required"
                    ValidationGroup="UpdateCustomerVG" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Region:</th>
                <td>
                </td>
                <td>
                  <asp:TextBox ID="RegionTextBox"
                    runat="server" Text='<%# Bind("Region") %>' />
                  &nbsp;<asp:RequiredFieldValidator
                    ID="RegionRfv" runat="server"
                    ControlToValidate="RegionTextBox"
                    ErrorMessage="*" ToolTip="Region is required"
                    ValidationGroup="UpdateCustomerVG" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Postal Code:</th>
                <td>
                </td>
                <td>
                  <asp:TextBox ID="PostalCodeTextBox"
                    runat="server" Text='<%# Bind("PostalCode") %>' />
                  &nbsp;<asp:RequiredFieldValidator
                    ID="PostalCodeRfv"
                    runat="server" ControlToValidate="PostalCodeTextBox"
                    ErrorMessage="*" ToolTip="Postal code is required"
                    ValidationGroup="UpdateCustomerVG" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Country:</th>
                <td>
                </td>
                <td>
                  <asp:TextBox ID="CountryTextBox"
                    runat="server" Text='<%# Bind("Country") %>' />
                  &nbsp;<asp:RequiredFieldValidator
                    ID="CountryRfv" runat="server"
                    ControlToValidate="CountryTextBox"
                    ErrorMessage="*" ToolTip="Country is required"
                    ValidationGroup="UpdateCustomerVG" />
                </td>
              </tr>
              <tr>
                <td>
                </td>
                <td>
                </td>
                <td>
                  <asp:LinkButton ID="UpdateLinkButton"
                    CommandName="update"
                    ValidationGroup="UpdateCustomerVG"
                    Text="Update" runat="server" />&nbsp;
                  <asp:LinkButton ID="CancelLinkButton"
                    CommandName="cancel"
                    Text="Cancel" runat="server" />
                </td>
              </tr>
            </table>
          </asp:Panel>
        </td>
      </tr>
      <tr>
        <td colspan="2" style="font-size: 10px">
          &nbsp;</td>
      </tr>
    </table>
  </EditItemTemplate>
  <ItemTemplate>
    <table>
      <tr>
        <td colspan="2" style="font-size: 10px">
          &nbsp;</td>
      </tr>
      <tr>
        <td style="width: 5px;
          background-color: #4682B4">
          <asp:Panel ID="SidePanel"
            Width="5px" runat="server" />
        </td>
        <td>
          <asp:Panel ID="CustomerPanel"
            runat="server" CssClass="CustomerPanel">
            <table>
              <tr>
                <td style="width: 50px">
                </td>
                <td style="width: 5px">
                </td>
                <td style="width: 235px">
                </td>
              </tr>
              <tr>
                <td colspan="3">
                  <asp:Label ID="CompanyLabel"
                    Text='<%# Eval("CompanyName") %>'
                    runat="server" BackColor="DarkGray"
                    ForeColor="White" Width="290px"
                    Font-Bold="true" Style="vertical-align: middle;
                    padding: 2px 4px 4px 2px" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Contact:</th>
                <td>
                </td>
                <td>
                  <asp:Label ID="ContactLabel"
                    Text='<%# Eval("ContactName") %>'
                    runat="server" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Title:</th>
                <td>
                </td>
                <td>
                  <asp:Label ID="ContactTitleLabel"
                    Text='<%# Eval("ContactTitle") %>'
                    runat="server" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Phone:</th>
                <td>
                </td>
                <td>
                  <asp:Label ID="PhoneLabel"
                    Text='<%# Eval("Phone") %>'
                    runat="server" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Fax:</th>
                <td>
                </td>
                <td>
                  <asp:Label ID="FaxLabel"
                    Text='<%# Eval("Fax") %>'
                    runat="server" />
                </td>
              </tr>
              <tr>
                <td colspan="3">
                  <asp:CheckBox ID="FavouriteCustomerCheckBox"
                    runat="server" Text="Favourite"
                    TextAlign="Right" />
                </td>
              </tr>
              <tr>
                <td>
                </td>
                <td>
                </td>
                <td>
                  <asp:LinkButton ID="DetailLinkButton"
                    CommandName="select"
                    Text="Detail" runat="server" />&nbsp;
                  <asp:LinkButton ID="EditLinkButton"
                    CommandName="Edit"
                    Text="Edit" runat="server" />&nbsp;
                  <asp:LinkButton ID="OrderLinkButton"
                    OnClientClick='<%# GetClientClick(Eval("CustomerID")) %>'
                    Text="Show Orders"
                    runat="server" />
                </td>
              </tr>
            </table>
          </asp:Panel>
        </td>
      </tr>
      <tr>
        <td colspan="2" style="font-size: 10px">
          &nbsp;</td>
      </tr>
    </table>
  </ItemTemplate>
  <SelectedItemTemplate>
    <table>
      <tr>
        <td colspan="2" style="font-size: 10px">
          &nbsp;</td>
      </tr>
      <tr>
        <td style="width: 5px;
          background-color: #4682B4">
          <asp:Panel ID="SidePanel"
            Width="5px" runat="server" />
        </td>
        <td>
          <asp:Panel ID="CustomerPanel"
            runat="server" CssClass="CustomerPanel">
            <table>
              <tr>
                <td style="width: 50px">
                </td>
                <td style="width: 5px">
                </td>
                <td style="width: 235px">
                </td>
              </tr>
              <tr>
                <td colspan="3">
                  <asp:Label ID="CompanyLabel"
                    Text='<%# Eval("CompanyName") %>'
                    runat="server" BackColor="DarkGray"
                    ForeColor="White" Width="290px"
                    Font-Bold="true" Style="vertical-align: middle;
                    padding: 2px 4px 4px 2px" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Contact:</th>
                <td>
                </td>
                <td>
                  <asp:Label ID="ContactLabel"
                    Text='<%# Eval("ContactName") %>'
                    runat="server" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Title:</th>
                <td>
                </td>
                <td>
                  <asp:Label ID="ContactTitleLabel"
                    Text='<%# Eval("ContactTitle") %>'
                    runat="server" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Phone:</th>
                <td>
                </td>
                <td>
                  <asp:Label ID="PhoneLabel"
                    Text='<%# Eval("Phone") %>'
                    runat="server" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Fax:</th>
                <td>
                </td>
                <td>
                  <asp:Label ID="FaxLabel"
                    Text='<%# Eval("Fax") %>'
                    runat="server" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Address:</th>
                <td>
                </td>
                <td>
                  <asp:Label ID="AddressLabel"
                    Text='<%# Eval("Address") %>'
                    runat="server" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  City:</th>
                <td>
                </td>
                <td>
                  <asp:Label ID="CityLabel"
                    Text='<%# Eval("City") %>'
                    runat="server" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Region:</th>
                <td>
                </td>
                <td>
                  <asp:Label ID="RegionLabel"
                    Text='<%# Eval("Region") %>'
                    runat="server" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Postal Code:</th>
                <td>
                </td>
                <td>
                  <asp:Label ID="PostalCodeLabel"
                    Text='<%# Eval("PostalCode") %>'
                    runat="server" />
                </td>
              </tr>
              <tr>
                <th align="right">
                  Country:</th>
                <td>
                </td>
                <td>
                  <asp:Label ID="CountryLabel"
                    Text='<%# Eval("Country") %>'
                    runat="server" />
                </td>
              </tr>
              <tr>
                <td>
                </td>
                <td>
                </td>
                <td>
                  <asp:LinkButton ID="SummaryLinkButton"
                    CommandName="summary"
                    Text="Summary" runat="server" />&nbsp;
                  <asp:LinkButton ID="EditLinkButton"
                    CommandName="Edit"
                    Text="Edit" runat="server" />
                </td>
              </tr>
            </table>
          </asp:Panel>
        </td>
      </tr>
      <tr>
        <td colspan="2" style="font-size: 10px">
          &nbsp;</td>
      </tr>
    </table>
  </SelectedItemTemplate>
</asp:DataList>
The following code snippet illustrates the SqlDataSource setup.
<asp:SqlDataSource ID="CustomerSqlDataSource"
  runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
  SelectCommand="SELECT * FROM [Customers] WHERE [CompanyName] LIKE '%' + @CompanyName + '%' OR @CompanyName = '-1'"
  UpdateCommand="UPDATE [Customers] SET [CompanyName] = @CompanyName, [ContactName] = @ContactName, [ContactTitle] = @ContactTitle, [Address] = @Address, [City] = @City, [Region] = @Region, [PostalCode] = @PostalCode, [Country] = @Country, [Phone] = @Phone, [Fax] = @Fax WHERE [CustomerID] = @CustomerID"
  DeleteCommand="DELETE FROM [Customers] WHERE [CustomerID] = @CustomerID"
  InsertCommand="INSERT INTO [Customers] ([CustomerID], [CompanyName], [ContactName], [ContactTitle], [Address], [City], [Region], [PostalCode], [Country], [Phone], [Fax]) VALUES (@CustomerID, @CompanyName, @ContactName, @ContactTitle, @Address, @City, @Region, @PostalCode, @Country, @Phone, @Fax)">
  <UpdateParameters>
    <asp:Parameter Name="CompanyName"
      Type="String" />
    <asp:Parameter Name="ContactName"
      Type="String" />
    <asp:Parameter Name="ContactTitle"
      Type="String" />
    <asp:Parameter Name="Address"
      Type="String" />
    <asp:Parameter Name="City"
      Type="String" />
    <asp:Parameter Name="Region"
      Type="String" />
    <asp:Parameter Name="PostalCode"
      Type="String" />
    <asp:Parameter Name="Country"
      Type="String" />
    <asp:Parameter Name="Phone"
      Type="String" />
    <asp:Parameter Name="Fax"
      Type="String" />
    <asp:Parameter Name="CustomerID"
      Type="String" />
  </UpdateParameters>
  <DeleteParameters>
    <asp:Parameter Name="CustomerID"
      Type="String" />
  </DeleteParameters>
  <InsertParameters>
    <asp:Parameter Name="CustomerID"
      Type="String" />
    <asp:Parameter Name="CompanyName"
      Type="String" />
    <asp:Parameter Name="ContactName"
      Type="String" />
    <asp:Parameter Name="ContactTitle"
      Type="String" />
    <asp:Parameter Name="Address"
      Type="String" />
    <asp:Parameter Name="City"
      Type="String" />
    <asp:Parameter Name="Region"
      Type="String" />
    <asp:Parameter Name="PostalCode"
      Type="String" />
    <asp:Parameter Name="Country"
      Type="String" />
    <asp:Parameter Name="Phone"
      Type="String" />
    <asp:Parameter Name="Fax"
      Type="String" />
  </InsertParameters>
  <SelectParameters>
    <asp:ControlParameter
      ControlID="SearchTextBox"
      DefaultValue="-1" Name="CompanyName"
      PropertyName="Text" />
  </SelectParameters>
</asp:SqlDataSource>
The following diagram illustrates the result of binding the DataList control to a SqlDataSource. The content is rendered based on the template definition as demonstrated in the DataList code snipet above

Search Data
One can filter the results of a DataList control by editing the SqlDataSource object to have a select parameter that represents the following.
<SelectParameters>
    <asp:ControlParameter
      ControlID="SearchTextBox"
      DefaultValue="-1" Name="CompanyName"
      PropertyName="Text" />
</SelectParameters>
As can be seen by the code snippet above, the value of the SearchTextBox (as seen below)is used as an input to the Select query specified for the SqlDataSource.
Search
The results of performing a search can be seen as follows.
SearchResult 
Edit/Update behaviour with the ASP.NET RequiredFieldValidator
Please refer to the DataList code snippet above. The snippet illustrates the configuration required to allow editing behaviour on the DataList control. Also refer to the SqlDataSource code snippet above that illustrates the setup required to enable updating on the DataList control. Furthermore, the following C# code snippets illustrate the event handlers related to editing and updating a DataList control item.
The Edit Command is as follows:
protected void CustomerDataList_EditCommand(
  object source, DataListCommandEventArgs e)
{
  CustomerDataList.EditItemIndex = (int)e.Item.ItemIndex;

  CustomerDataList.DataBind();
}
The Update Command is as follows:
protected void CustomerDataList_UpdateCommand(
  object source, DataListCommandEventArgs e)
{
  string customerId = CustomerDataList.DataKeys[e.Item.ItemIndex].ToString();

  string companyName = ((TextBox)e.Item.FindControl("CompanyNameTextBox")).Text;

  string contactName = ((TextBox)e.Item.FindControl("ContactNameTextBox")).Text;

  string contactTitle = ((TextBox)e.Item.FindControl("ContactTitleTextBox")).Text;

  string phone = ((TextBox)e.Item.FindControl("PhoneTextBox")).Text;

  string fax = ((TextBox)e.Item.FindControl("FaxTextBox")).Text;

  string address = ((TextBox)e.Item.FindControl("AddressTextBox")).Text;

  string city = ((TextBox)e.Item.FindControl("CityTextBox")).Text;

  string region = ((TextBox)e.Item.FindControl("RegionTextBox")).Text;

  string postalCode = ((TextBox)e.Item.FindControl("PostalCodeTextBox")).Text;

  string country = ((TextBox)e.Item.FindControl("CountryTextBox")).Text;

  CustomerSqlDataSource.UpdateParameters["CustomerID"].DefaultValue = customerId;

  CustomerSqlDataSource.UpdateParameters["CompanyName"].DefaultValue = companyName;

  CustomerSqlDataSource.UpdateParameters["ContactName"].DefaultValue = contactName;

  CustomerSqlDataSource.UpdateParameters["ContactTitle"].DefaultValue = contactTitle;

  CustomerSqlDataSource.UpdateParameters["Phone"].DefaultValue = phone;

  CustomerSqlDataSource.UpdateParameters["Fax"].DefaultValue = fax;

  CustomerSqlDataSource.UpdateParameters["Address"].DefaultValue = address;

  CustomerSqlDataSource.UpdateParameters["City"].DefaultValue = city;

  CustomerSqlDataSource.UpdateParameters["Region"].DefaultValue = region;

  CustomerSqlDataSource.UpdateParameters["PostalCode"].DefaultValue = postalCode;

  CustomerSqlDataSource.UpdateParameters["Country"].DefaultValue = country;

  CustomerSqlDataSource.Update();

  CustomerDataList.EditItemIndex = -1;

  CustomerDataList.DataBind();
}
The Cancel Command is as follows:
protected void CustomerDataList_CancelCommand(
  object source, DataListCommandEventArgs e)
{
  CustomerDataList.EditItemIndex = -1;

  CustomerDataList.DataBind();
}
The result of performing an Edit/Update operation is as follows:
Edit 
Select Behaviour
For the demonstration of the Select behaviour, we will toggle between a summarised and detailed view of customer information. Please refer to the DataList and SqlDataSource code snippets above to see how the select behaviour is configured. Furthermore, the ItemCommand event is used in terms of selecting a DataList control item. The event handling code is demonstrated as follows.
protected void CustomerDataList_ItemCommand(
  object source, DataListCommandEventArgs e)
{
  if (e.CommandName == "select")
  {
    CustomerDataList.SelectedIndex = e.Item.ItemIndex;
  }
  else if (e.CommandName == "summary")
  {
    CustomerDataList.SelectedIndex = -1;
  }

  DataBind();
}
Because of event 'Bubbling', one is able to intercept the event that is raised by the child control (LinkButton in this case)
The result of selecting an item is a more detailed display of customer information as is illustrated below.
Select 
Determine Selected Item/s
One is able to determine the selected items of a DataList control. Instead of using event 'Bubbling', I have chosen to add a click event handler directly to the 'View Favourite Customers' LinkButton. The event handling code is illustrated as follows.
protected void ViewFavouriteCustomers_LinkButton_Click(
  object sender, EventArgs e)
{
  FavouriteCustomerList.Clear();

  if (CustomerDataList.Items.Count > 0)
  {
    foreach (DataListItem item in CustomerDataList.Items)
    {
      CheckBox favouriteCustomerCheckBox =
        item.FindControl("FavouriteCustomerCheckBox"as CheckBox;

      if (favouriteCustomerCheckBox != null &&
        favouriteCustomerCheckBox.Checked)
      {
        Label companyNameLabel = item.FindControl(
          "CompanyLabel"as Label;

        Label contactLabel = item.FindControl(
          "ContactLabel"as Label;

        if (companyNameLabel != null && contactLabel != null)
        {
          FavouriteCustomerList.Add(String.Format("{0} - {1}",
            companyNameLabel.Text, contactLabel.Text));
        }
      }
    }

    if (FavouriteCustomerList.Count > 0)
    {
      StringBuilder sb = new StringBuilder();

      foreach (String customer in FavouriteCustomerList)
      {
        sb.AppendFormat("{0}<br/>", customer);
      }

      FavouriteCustomerListLabel.Text = sb.ToString();

    }
  }
}
All that is happening is that the code is iterating through all items in the DataList and finds a checkbox that is selected. This is one possible way in which one can check for selected items in a DataList control.
The results are as follows:
ViewFavourites 
Master/Details using a modal dialog
Using some javascript and a LinkButton, the DataList control will allow one to open a modal dialog that will display any orders pertaining to the customer from which the modal dialog was launched. What this means is that customer id associated with a customer template will be passed as a querystring to the modal dialog. When the Order page opens within the modal dialog, a list of orders will be displayed based on the customer id querystring. In order to achieve this functionality, one is required to add the following code to the 'OnClientClick' event of the 'Show Orders' LinkButton.
<asp:LinkButton ID="OrderLinkButton"
     OnClientClick='<%# GetClientClick(Eval("CustomerID")) %>'
     Text="Show Orders"
     runat="server" />
The 'GetClientClick' code simply returns the javascript required to open a modal dialog and is illustrated as follows.
protected static string GetClientClick(object value)
{
  return String.Format(
    "ShowOrderReport('{0}'); return false;",
    value.ToString());
}
The javascript code is embedded into the 'CustomerContacts' page and is illustrated as follows.
<script language="javascript" type="text/javascript">

    /**
    * Show a modal dialog that will load a page containing a Repeater
    * that will be populated with Order records based on the
    * provided 'CustomerID'
    */
    function ShowOrderReport(CustomerID)
    {
      window.showModalDialog("OrderReport.aspx?CustomerID=" + CustomerID, "",
        "dialogWidth:800px;dialogHeight:400px;resizable:no;scrollbars:no");
    }

</script>
The result is as follows.
Repeater
The Repeater control code snippet is demonstrated as follows.

Bind Repeater to SqlDataSource using QueryString parameter
The Repeater data control is setup as follows. Please take note of the templates. Spanning html over multiple templates is unique to the Repeater data control.
<asp:Repeater ID="OrderRepeater"
  runat="server" DataSourceID="OrderSqlDataSource">
  <HeaderTemplate>
    <table class="OrderTable">
      <tr style="background-color: #696969;
        color: White;">
        <th>
          Order Id</th>
        <th>
          Product</th>
        <th>
          Quantity</th>
        <th>
          Unit Price</th>
        <th>
          Order Date</th>
        <th>
          Required Date</th>
        <th>
          Shipped Date</th>
      </tr>
  </HeaderTemplate>
  <AlternatingItemTemplate>
    <tr style="background-color: Gainsboro;">
      <td>
        <asp:Label ID="OrderIdLabel"
          Text='<%# Eval("OrderID") %>'
          runat="server" />
      </td>
      <td>
        <asp:Label ID="ProductLabel"
          Text='<%# Eval("Product") %>'
          runat="server" />
      </td>
      <td align="center">
        <asp:Label ID="QuantityLabel"
          Text='<%# Eval("Quantity") %>'
          runat="server" />
      </td>
      <td>
        <asp:Label ID="UnitPriceLabel"
          Text='<%# DataBinder.Eval(Container.DataItem, "UnitPrice", "{0:c}") %>'
          runat="server" />
      </td>
      <td>
        <asp:Label ID="OrderDateLabel"
          Text='<%# GetDate(Eval("OrderDate")) %>'
          runat="server" />
      </td>
      <td>
        <asp:Label ID="RequiredDateLabel"
          Text='<%# GetDate(Eval("RequiredDate")) %>'
          runat="server" />
      </td>
      <td>
        <asp:Label ID="ShippedDateLabel"
          Text='<%# GetDate(Eval("ShippedDate")) %>'
          runat="server" />
      </td>
    </tr>
  </AlternatingItemTemplate>
  <ItemTemplate>
    <tr style="background-color: LightSteelBlue;">
      <td>
        <asp:Label ID="OrderIdLabel"
          Text='<%# Eval("OrderID") %>'
          runat="server" />
      </td>
      <td>
        <asp:Label ID="ProductLabel"
          Text='<%# Eval("Product") %>'
          runat="server" />
      </td>
      <td align="center">
        <asp:Label ID="QuantityLabel"
          Text='<%# Eval("Quantity") %>'
          runat="server" />
      </td>
      <td>
        <asp:Label ID="UnitPriceLabel"
          Text='<%# DataBinder.Eval(Container.DataItem, "UnitPrice", "{0:c}") %>'
          runat="server" />
      </td>
      <td>
        <asp:Label ID="OrderDateLabel"
          Text='<%# GetDate(Eval("OrderDate")) %>'
          runat="server" />
      </td>
      <td>
        <asp:Label ID="RequiredDateLabel"
          Text='<%# GetDate(Eval("RequiredDate")) %>'
          runat="server" />
      </td>
      <td>
        <asp:Label ID="ShippedDateLabel"
          Text='<%# GetDate(Eval("ShippedDate")) %>'
          runat="server" />
      </td>
    </tr>
  </ItemTemplate>
  <FooterTemplate>
    </table>
  </FooterTemplate>
</asp:Repeater>
The SqlDataSource to which the Repeater binds via the Repeater DataSourceID property is illustrated below. Please take note of the use of the QueryString parameter.
<asp:SqlDataSource ID="OrderSqlDataSource"
  runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
  SelectCommand="SELECT O.OrderID [OrderID], O.OrderDate [OrderDate], O.RequiredDate [RequiredDate], O.ShippedDate [ShippedDate], OD.UnitPrice [UnitPrice], OD.Quantity [Quantity], P.ProductName [Product] FROM [Orders] O&#13;&#10;JOIN [Order Details] OD ON O.OrderID = OD.OrderID&#13;&#10;JOIN [Products] P ON OD.ProductID = P.ProductID&#13;&#10;WHERE O.CustomerID = @CustomerId">
  <SelectParameters>
    <asp:QueryStringParameter
      DefaultValue="-1" Name="CustomerId"
      QueryStringField="CustomerID" />
  </SelectParameters>
</asp:SqlDataSource>
Use custom method to format date as part of DataBinding
Formatting the date can be achieved by specifying the format much the same way as has been done for the currency.
<asp:Label ID="UnitPriceLabel"
              Text='<%# DataBinder.Eval(Container.DataItem, "UnitPrice", "{0:c}") %>'
              runat="server" />
I would however like to demonstrate how one is able to use a server method to do 'stuff'. Therefore, the code required to use a server method is as follows.
<td>
  <asp:Label ID="OrderDateLabel"
    Text='<%# GetDate(Eval("OrderDate")) %>'
    runat="server" />
</td>
<td>
  <asp:Label ID="RequiredDateLabel"
    Text='<%# GetDate(Eval("RequiredDate")) %>'
    runat="server" />
</td>
<td>
  <asp:Label ID="ShippedDateLabel"
    Text='<%# GetDate(Eval("ShippedDate")) %>'
    runat="server" />
</td>
The server method itself is illustrated as follows.
protected string GetDate(object value)
{
  DateTime result;

  DateTime.TryParse(value.ToString(), out result);

  return result.ToString("dd MMM yyyy");
}
Columns, Layout and Orientation
One is able to change simple properties in terms of the way the DataList will render contents. This is best illustrated in the following code snippet. The code snippet illustrates how one is able to change the number of columns a DataList uses, the layout, and the orientation. The 'RepeatColumns' property determines the number of columns in which content will display. The 'RepeatDirection' property determines the orientation (Vertical or horizontal). The 'RepeatLayout' property determines the layout (Flow or Table).
protected void RepeatColumnsDropDownList_SelectedIndexChanged(
  object sender, EventArgs e)
{
  CustomerDataList.RepeatColumns = int.Parse(
    RepeatColumnsDropDownList.SelectedValue);
}

protected void RepeatDirectionDropDownList_SelectedIndexChanged(
  object sender, EventArgs e)
{
  if (RepeatDirectionDropDownList.SelectedValue == "Horizontal")
  {
    CustomerDataList.RepeatDirection = RepeatDirection.Horizontal;
  }
  else
  {
    CustomerDataList.RepeatDirection = RepeatDirection.Vertical;
  }
}

protected void RepeatLayoutDropDownList_SelectedIndexChanged(
  object sender, EventArgs e)
{
  if (RepeatLayoutDropDownList.SelectedValue == "Flow")
  {
    CustomerDataList.RepeatLayout = RepeatLayout.Flow;
  }
  else
  {
    CustomerDataList.RepeatLayout = RepeatLayout.Table;
  }
}
Furthermore, the following html code is required to create the controls that will change the DataList properties.
<asp:Panel ID="DataListConfigurationPanel"
  runat="server" CssClass="Panel">
  <table>
    <tr>
      <td>
        Repeat Columns:</td>
      <td>
        <asp:DropDownList ID="RepeatColumnsDropDownList"
          runat="server" AutoPostBack="True"
          OnSelectedIndexChanged="RepeatColumnsDropDownList_SelectedIndexChanged">
          <asp:ListItem Text="1"
            Value="1" />
          <asp:ListItem Text="2"
            Value="2" />
          <asp:ListItem Text="3"
            Value="3" />
        </asp:DropDownList></td>
    </tr>
    <tr>
      <td>
        Repeat Direction:</td>
      <td>
        <asp:DropDownList ID="RepeatDirectionDropDownList"
          runat="server" AutoPostBack="True"
          OnSelectedIndexChanged="RepeatDirectionDropDownList_SelectedIndexChanged">
          <asp:ListItem Text="Horizontal"
            Value="Horizontal" />
          <asp:ListItem Text="Vertical"
            Value="Vertical" />
        </asp:DropDownList></td>
    </tr>
    <tr>
      <td>
        Repeat Layout:</td>
      <td>
        <asp:DropDownList ID="RepeatLayoutDropDownList"
          runat="server" AutoPostBack="True"
          OnSelectedIndexChanged="RepeatLayoutDropDownList_SelectedIndexChanged">
          <asp:ListItem Text="Flow"
            Value="Flow" />
          <asp:ListItem Text="Table"
            Value="Table" />
        </asp:DropDownList></td>
    </tr>
  </table>
</asp:Panel>
The following screenshot illustrates the controls that are used to change the DataList proeprties.
Config


Thats it for this version of the ASP.NET Data Control Series. I will be adding to this series in the future in terms of using ASP.NET Data Controls with ASP.NET AJAX. Also, as I think of things that one would not normally do with these controls, I will share those ideas too. Readers comments are most valuable in terms of understanding whether I have pitched this series at the correct level. Also, any other questions pertaining to these controls are most welcome. This will help the knowledge, in terms of understanding these controls better, grow.

No comments:

Post a Comment

Flipkart