November 22, 2014
Hot Topics:

DataBinding a DropDownList in a FormView

  • May 22, 2009
  • By Paul Kimmel
  • Send Email »
  • More Articles »

Introduction DataBinding a DropDownList in a FormView

An old friend of mine, Joe Shook, laughingly said, “you should read what other people write too once in a while.” Of course, he was right and naturally I do. I must. I read almost everything I can get in my hands including technical books, blogs, and articles because I am surprised by the number of things I haven't mastered or that I still don't have a “best practices” sort of solution for.

News flash: Paul doesn't know everything. Thankfully I am still willing to stay up to 11 or 12 o'clock—used to be until the next morning—working out the details of what I don't know until I am happy with an answer.

A friend of mine actually asked me about this particular problem: what is a good way to bind a DropDownList in a FormView. Since this particular challenge wasn't on my radar I provided him with a workable solution, but thought a better solution was possible. This article provides a comprehensive solution for defining an edit template in a FormView. The edit template contains a DropDownList and the population, binding, and updating is all handled declaratively.

Defining an Edit Template for a FormView

The FormView was introduced in .NET 2.0. The FormView is a binding control like the GridView, except where the GridView shows multiple rows of data and the FormView shows one record at a time in a form layout.

To get started you will need to complete these steps:

  • Add a WebForm to your project
  • From the Smart tags menu select Choose Data Source, configure the Northwind data source and the Orders table
  • When you specify the columns and table select all columns from the Orders table
  • On the Configure Select Statement click Advanced and check Generate INSERT, UPDATE, and DELETE statements (see Figure 1)
  • Click OK.
  • Click Next
  • Click Finish to generate the SqlDataSource

After you complete the data source wizard the FormView will have controls added to it for the ItemTemplate, EditItemTemplate, and InsertItemTemplate. It is the EditItemTemplate you are interested in. The EditItemTemplate will contain TextBox controls by default. The TextBox controls provide basic data entry support for editing a record.


Figure 1: Check the Generate option to configure declarative INSERT, UPDATE, and DELETE SQL statements for a data source.

The next step is to change out a TextBox for a DropDownList in the EditItemTemplate and get data into the DropDownList.

Configuring and DataBinding the DropDownList

To demonstrate data binding for a DropDownList in a FormView switch the FormView to the EditItemTemplate. You can use the Smart tags menu or switch to the ASP.NET view and replace the CustomerID TextBox with a DropDownList. Next you will need to configure the data source for the DropDownList and bind the DropDownList to the source for the list items and the source for the selected value. Here are the steps:

  • In EditItemTemplate add a DropDownList in place of the TextBox for the CustomerID (removing the TextBox)
  • In the designer in EditItemTemplate select the Smart tags menu for the DropDownList and select Choose Data Source
  • In the Data Source Configuration Wizard choose New Data Source
  • Select a SqlDataSource and name it CustomerIDDataSource
  • Select the Northwind database in the connection string step
  • Pick the Customers table and check the CustomerID and CompanyName fields (see Figure 2)
  • Complete the wizard


Figure 2: Configuring the lookup data source.

The last steps require that you bind the DataTextField and DataValueField properties to the CustomerIDDataSource and the SelectedValue to the original source's CustomerID. The DropDownList should be configured to look like the ASP.NET fragment below.

<asp:DropDownList ID="CustomerIDDropDownList" runat="server"
  DataValueField='CustomerID' DataSourceID="CustomerIDDataSource" 
  DataTextField="CompanyName" 
  SelectedValue='<%# Eval("CustomerID") %>'
/>

The DataSourceID for the DropDownList points at CustomerIDDataSource. The DataValueField and DataTextField's are assigned to CustomerID and CompanyName respectively, and lookup values will come from the Customers table. The Eval method in the script block implies that the SelectedValue is read from the outer data source's CustomerID field.

Bind and Eval perform approximately the same function, reading data from a data source. The difference is that Bind is a two-way bind (read and write) and Eval is a one way bind (read-only) from the DataSource. If you use Eval as shown above then you will have to set the value when it changes in the FormViewIttemUpdate event (see Listing 1). If you switch Eval to Bind for the SelectedValue then no code-behind is required.

Listing 1: If you want to set the selected value for write programmatically implement the ItemUpdating event handler.

Protected Sub FormView1_ItemUpdating(ByVal sender As Object, _
  ByVal e As System.Web.UI.WebControls.FormViewUpdateEventArgs) _
  Handles FormView1.ItemUpdating
 
  Dim control As DropDownList = FormView1.FindControl("CustomerIDDropDownList")
  e.NewValues("CustomerID") = control.SelectedValue
 
End Sub

Use Bind for the DropDownList SelectedValue and the code in Listing 1 is not needed. If you use Eval then remember that the DropDownList is in a template of the FormView, so you have to get the actual DropDownList by calling FindControl and setting the updated value to the e.NewValues property.

That's it. Modify the CustomerID by picking a Customer from the DropDownList and click the Update button provided by the FormView designer. The running form is shown in Figure 3, and the ASP.NET showing all of the elements generated by the designer (or added by you) is provided in Listing 2.


Figure 3: The running form with the DropDownList.

Listing 2: All of the code-behind. If you follow the steps only the basic binding statements for the DropDownList need be modified.

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" 
         Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
      <asp:FormView ID="FormView1" runat="server" DataKeyNames="OrderID" 
        DataSourceID="SqlDataSource1" DefaultMode="Edit">
        <EditItemTemplate>
          OrderID:
          <asp:Label ID="OrderIDLabel1" runat="server" Text='<%# Eval("OrderID") %>' />
          <br />
          CustomerID:
          <asp:DropDownList ID="CustomerIDDropDownList" runat="server"
            DataValueField='CustomerID' DataSourceID="CustomerDataSource" 
            DataTextField="CompanyName" 
            SelectedValue='<%# Bind("CustomerID") %>'
            />
          <asp:SqlDataSource ID="CustomerDataSource" runat="server" 
            ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
            SelectCommand="SELECT [CustomerID], [CompanyName] FROM [Customers]">
          </asp:SqlDataSource>
         <br />
          EmployeeID:
          <asp:TextBox ID="EmployeeIDTextBox" runat="server" 
            Text='<%# Bind("EmployeeID") %>' />
          <br />
          OrderDate:
          <asp:TextBox ID="OrderDateTextBox" runat="server" 
            Text='<%# Bind("OrderDate") %>' />
          <br />
          RequiredDate:
          <asp:TextBox ID="RequiredDateTextBox" runat="server" 
            Text='<%# Bind("RequiredDate") %>' />
          <br />
          ShippedDate:
          <asp:TextBox ID="ShippedDateTextBox" runat="server" 
            Text='<%# Bind("ShippedDate") %>' />
          <br />
          ShipVia:
          <asp:TextBox ID="ShipViaTextBox" runat="server" Text='<%# Bind("ShipVia") %>' />
          <br />
          Freight:
          <asp:TextBox ID="FreightTextBox" runat="server" Text='<%# Bind("Freight") %>' />
          <br />
          ShipName:
          <asp:TextBox ID="ShipNameTextBox" runat="server" 
            Text='<%# Bind("ShipName") %>' />
          <br />
          ShipAddress:
          <asp:TextBox ID="ShipAddressTextBox" runat="server" 
            Text='<%# Bind("ShipAddress") %>' />
          <br />
          ShipCity:
          <asp:TextBox ID="ShipCityTextBox" runat="server" 
            Text='<%# Bind("ShipCity") %>' />
          <br />
          ShipRegion:
          <asp:TextBox ID="ShipRegionTextBox" runat="server" 
            Text='<%# Bind("ShipRegion") %>' />
          <br />
          ShipPostalCode:
          <asp:TextBox ID="ShipPostalCodeTextBox" runat="server" 
            Text='<%# Bind("ShipPostalCode") %>' />
          <br />
          ShipCountry:
          <asp:TextBox ID="ShipCountryTextBox" runat="server" 
            Text='<%# Bind("ShipCountry") %>' />
          <br />
          <asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" 
            CommandName="Update" Text="Update" />
           <asp:LinkButton ID="UpdateCancelButton" runat="server" 
            CausesValidation="False" CommandName="Cancel" Text="Cancel" />
        </EditItemTemplate>
        <InsertItemTemplate>
          CustomerID:
          <asp:TextBox ID="CustomerIDTextBox" runat="server" 
            Text='<%# Bind("CustomerID") %>' />
          <br />
          EmployeeID:
          <asp:TextBox ID="EmployeeIDTextBox" runat="server" 
            Text='<%# Bind("EmployeeID") %>' />
          <br />
          OrderDate:
          <asp:TextBox ID="OrderDateTextBox" runat="server" 
            Text='<%# Bind("OrderDate") %>' />
          <br />
          RequiredDate:
          <asp:TextBox ID="RequiredDateTextBox" runat="server" 
            Text='<%# Bind("RequiredDate") %>' />
          <br />
          ShippedDate:
          <asp:TextBox ID="ShippedDateTextBox" runat="server" 
            Text='<%# Bind("ShippedDate") %>' />
          <br />
          ShipVia:
          <asp:TextBox ID="ShipViaTextBox" runat="server" Text='<%# Bind("ShipVia") %>' />
          <br />
          Freight:
          <asp:TextBox ID="FreightTextBox" runat="server" Text='<%# Bind("Freight") %>' />
          <br />
          ShipName:
          <asp:TextBox ID="ShipNameTextBox" runat="server" 
            Text='<%# Bind("ShipName") %>' />
          <br />
          ShipAddress:
          <asp:TextBox ID="ShipAddressTextBox" runat="server" 
            Text='<%# Bind("ShipAddress") %>' />
          <br />
          ShipCity:
          <asp:TextBox ID="ShipCityTextBox" runat="server" 
            Text='<%# Bind("ShipCity") %>' />
          <br />
          ShipRegion:
          <asp:TextBox ID="ShipRegionTextBox" runat="server" 
            Text='<%# Bind("ShipRegion") %>' />
          <br />
          ShipPostalCode:
          <asp:TextBox ID="ShipPostalCodeTextBox" runat="server" 
            Text='<%# Bind("ShipPostalCode") %>' />
          <br />
          ShipCountry:
          <asp:TextBox ID="ShipCountryTextBox" runat="server" 
            Text='<%# Bind("ShipCountry") %>' />
          <br />
          <asp:LinkButton ID="InsertButton" runat="server" CausesValidation="True" 
            CommandName="Insert" Text="Insert" />
           <asp:LinkButton ID="InsertCancelButton" runat="server" 
            CausesValidation="False" CommandName="Cancel" Text="Cancel" />
        </InsertItemTemplate>
        <ItemTemplate>
          OrderID:
          <asp:Label ID="OrderIDLabel" runat="server" Text='<%# Eval("OrderID") %>' />
          <br />
          CustomerID:
          <asp:Label ID="CustomerIDLabel" runat="server" 
            Text='<%# Bind("CustomerID") %>' />
          <br />
          EmployeeID:
          <asp:Label ID="EmployeeIDLabel" runat="server" 
            Text='<%# Bind("EmployeeID") %>' />
          <br />
          OrderDate:
          <asp:Label ID="OrderDateLabel" runat="server" Text='<%# Bind("OrderDate") %>' />
          <br />
          RequiredDate:
          <asp:Label ID="RequiredDateLabel" runat="server" 
            Text='<%# Bind("RequiredDate") %>' />
          <br />
          ShippedDate:
          <asp:Label ID="ShippedDateLabel" runat="server" 
            Text='<%# Bind("ShippedDate") %>' />
          <br />
          ShipVia:
          <asp:Label ID="ShipViaLabel" runat="server" Text='<%# Bind("ShipVia") %>' />
          <br />
          Freight:
          <asp:Label ID="FreightLabel" runat="server" Text='<%# Bind("Freight") %>' />
          <br />
          ShipName:
          <asp:Label ID="ShipNameLabel" runat="server" Text='<%# Bind("ShipName") %>' />
          <br />
          ShipAddress:
          <asp:Label ID="ShipAddressLabel" runat="server" 
            Text='<%# Bind("ShipAddress") %>' />
          <br />
          ShipCity:
          <asp:Label ID="ShipCityLabel" runat="server" Text='<%# Bind("ShipCity") %>' />
          <br />
          ShipRegion:
          <asp:Label ID="ShipRegionLabel" runat="server" 
            Text='<%# Bind("ShipRegion") %>' />
          <br />
          ShipPostalCode:
          <asp:Label ID="ShipPostalCodeLabel" runat="server" 
            Text='<%# Bind("ShipPostalCode") %>' />
          <br />
          ShipCountry:
          <asp:Label ID="ShipCountryLabel" runat="server" 
            Text='<%# Bind("ShipCountry") %>' />
          <br />
          <asp:LinkButton ID="EditButton" runat="server" CausesValidation="False" 
            CommandName="Edit" Text="Edit" />
           <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False" 
            CommandName="Delete" Text="Delete" />
           <asp:LinkButton ID="NewButton" runat="server" CausesValidation="False" 
            CommandName="New" Text="New" />
        </ItemTemplate>
      </asp:FormView>
      <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
        ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
        SelectCommand="SELECT * FROM [Orders]" 
        DeleteCommand="DELETE FROM [Orders] WHERE [OrderID] = @OrderID" 
        InsertCommand="INSERT INTO [Orders] ([CustomerID], [EmployeeID], [OrderDate], 
[RequiredDate], [ShippedDate], [ShipVia], [Freight], [ShipName], [ShipAddress], [ShipCity], 
[ShipRegion], [ShipPostalCode], [ShipCountry]) VALUES (@CustomerID, @EmployeeID, 
@OrderDate, @RequiredDate, @ShippedDate, @ShipVia, @Freight, @ShipName, 
@ShipAddress, @ShipCity, @ShipRegion, @ShipPostalCode, @ShipCountry)" 
        UpdateCommand="UPDATE [Orders] SET [CustomerID] = @CustomerID, [EmployeeID] = 
@EmployeeID, [OrderDate] = @OrderDate, [RequiredDate] = @RequiredDate, [ShippedDate] = 
@ShippedDate, [ShipVia] = @ShipVia, [Freight] = @Freight, [ShipName] = @ShipName, 
[ShipAddress] = @ShipAddress, [ShipCity] = @ShipCity, [ShipRegion] = @ShipRegion, 
[ShipPostalCode] = @ShipPostalCode, [ShipCountry] = @ShipCountry WHERE [OrderID] = 
@OrderID">
        <DeleteParameters>
          <asp:Parameter Name="OrderID" Type="Int32" />
        </DeleteParameters>
        <UpdateParameters>
          <asp:Parameter Name="CustomerID" Type="String" />
          <asp:Parameter Name="EmployeeID" Type="Int32" />
          <asp:Parameter Name="OrderDate" Type="DateTime" />
          <asp:Parameter Name="RequiredDate" Type="DateTime" />
          <asp:Parameter Name="ShippedDate" Type="DateTime" />
          <asp:Parameter Name="ShipVia" Type="Int32" />
          <asp:Parameter Name="Freight" Type="Decimal" />
          <asp:Parameter Name="ShipName" Type="String" />
          <asp:Parameter Name="ShipAddress" Type="String" />
          <asp:Parameter Name="ShipCity" Type="String" />
          <asp:Parameter Name="ShipRegion" Type="String" />
          <asp:Parameter Name="ShipPostalCode" Type="String" />
          <asp:Parameter Name="ShipCountry" Type="String" />
          <asp:Parameter Name="OrderID" Type="Int32" />
        </UpdateParameters>
        <InsertParameters>
          <asp:Parameter Name="CustomerID" Type="String" />
          <asp:Parameter Name="EmployeeID" Type="Int32" />
          <asp:Parameter Name="OrderDate" Type="DateTime" />
          <asp:Parameter Name="RequiredDate" Type="DateTime" />
          <asp:Parameter Name="ShippedDate" Type="DateTime" />
          <asp:Parameter Name="ShipVia" Type="Int32" />
          <asp:Parameter Name="Freight" Type="Decimal" />
          <asp:Parameter Name="ShipName" Type="String" />
          <asp:Parameter Name="ShipAddress" Type="String" />
          <asp:Parameter Name="ShipCity" Type="String" />
          <asp:Parameter Name="ShipRegion" Type="String" />
          <asp:Parameter Name="ShipPostalCode" Type="String" />
          <asp:Parameter Name="ShipCountry" Type="String" />
        </InsertParameters>
      </asp:SqlDataSource>
       
    </div>
    </form>
</body>
</html>

Summary

It took me a couple of hours to work out the details in a manner I was happy with. The key to binding is the second DataSource for the lookup and understanding the difference between Bind and Eval. Bind reads and writes and Eval only reads from the DataSource. Admittedly I hardly ever use binding and DataSources. I generally prefer custom objects and manually setting and getting data. For me, I have found that enterprise applications and applications of even modest complexity require a lot of business rules and control, and managing everything from scratch supports that from the get go. I do use Bind, Eval, and UserControls heavily though.

I encourage you to use whatever works for you in a given context, what will help you get the job done quickly, and employ techniques that you understand. And a big strategy is to use whatever approach works in an application even if it means mixing styles—custom versus data sources and binding. It's all just code. They key is to get done quickly with dependable and maintainable results.

About the Author

Paul Kimmel is the VB Today columnist for www.codeguru.com and has written several books on object-oriented programming and .NET. Check out his upcoming book LINQ Unleashed for C# now available on Amazon.com and fine bookstores everywhere. Look for his upcoming book Teach Yourself the ADO.NET Entity Framework in 24 Hours. You may contact him for technology questions at pkimmel@softconcepts.com. Paul Kimmel is a Technical Evangelist for Developer Express, Inc, and you can ask him about Developer Express at paulk@devexpress.com and read his DX blog at http://community.devexpress.com/blogs/paulk.

I just finished a small commitment with the Lansing GiveCamp, which was sponsored in part by Developer Express and am looking forward to seeing some of you at Tech Ed in Los Angeles. Check out our Developer Express area and make sure you sign up for our giveaways.






Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel