Including a DropDownListBox in an Editable DataGrid...

原创 2004年10月06日 18:32:00


By: John Kilgo Date: February 1, 2003 Download the code. Printer Friendly Version

The data choices for some database table columns are relatively fixed. Examples would be countries, states, and counties for instance. In these cases a dropdown list of fixed choices makes more sense than keyboard input where mistakes can be made easily. In an editable datagrid you can include dropdownlistboxes, although they must be populated at run time. You cannot do it at design time. In order to accomodate the dropdownlistbox the datagrid must use TemplateColumns with ItemTemplates.

For this article I have chosen to present selected data from the Northwind Customers table. The data includes a country column that is perfect for presentation with a dropdownlistbox when in edit mode.

As is usually the case in DotNetJohn articles, we will separate code from presentation by using an aspx page with a .vb code-behind page. The aspx page is presented first. The first part of the page, presented below, just defines our datagrid. There is nothing unusual about the design of the datagrid except that we setup for OnEditCommand, OnUpdateCommand, and OnCancelCommad event handlers. These are necessary for any datagrid to be placed in edit mode. The actual event handlers will be in our code-behind page.

<%@ Page Language="vb" Src="DataGridDropDown.aspx.vb" Inherits="DataGridDropDown" %>
<title>DataGrid with a DropDownListBox</title>
<form runat="server" ID="Form1">
<h3>DataGrid with a DropDownListBox</h3>
<asp:DataGrid ID="dtgCustomers" runat="server"

Next comes our TemplateColumns. We use asp:labels to hold data for presentation. All of this is pretty straight forward until we come to the code marked in blue. In the first few lines we have our ItemTemplate wherein the country will be shown when the datagrid is in presentation mode (i.e. not in edit mode). In this respect it is just like all of the other columns in the grid. We then include a label with its visible property set to false. This invisible label holds the CustomerID column. It is not needed for presentation but will be needed as a key field for our WHERE clause when updating the row. It could have been included elsewhere in the grid, but logically belongs with the section where data will be updated. (For purposes of this article only the country column will be updateable, although all columns could have been eligible for update.) Notice that we have made arrangements to present the country in two different places. The first is for normal presentation mode, while the second is so that we can see the existing value while we are in edit mode with the dropdownlistbox showing.

Finally comes our dropdownlist box. It is made ready by the line: DataSource="<%# BindTheCountry() %>". While we cannot populate the dropdown at design time, we can reference a function (BindTheCountry()) that will fill the dropdown at run time. BindTheCountry() will be seen in the code-behind page.

    <asp:EditCommandColumn EditText="Edit"
                          HeaderText="Commands" />

    <asp:TemplateColumn HeaderText="Company Name">
        <asp:Label ID="lblCompanyName"
                  Text='<%# DataBinder.Eval(Container.DataItem, "CompanyName") %>'
                  Runat="server" />

    <asp:TemplateColumn HeaderText="Contact Name">
        <asp:Label ID="lblContactName"
                  Text='<%# DataBinder.Eval(Container.DataItem, "ContactName") %>'
                  Runat="server" />

    <asp:TemplateColumn HeaderText="Contact Title">
        <asp:Label ID="lblContactTitle"
                  Text='<%# DataBinder.Eval(Container.DataItem, "ContactTitle") %>'
                  Runat="server" />

    <asp:TemplateColumn HeaderText="Country">
        <asp:Label ID="lblCountry"
                  Text='<%# DataBinder.Eval(Container.DataItem, "Country") %>'
                  Runat="server" />
        <asp:Label runat="server"
                  Text='<%# DataBinder.Eval(Container.DataItem, "CustomerID") %>'/>
        <asp:Label ID="lblTempState"
                  Text='<%# DataBinder.Eval(Container.DataItem, "Country") %>'
                  Runat="server" />
        <asp:DropDownList id="ddlCountry"
                          DataSource="<%# BindTheCountry() %>"
                          runat="server" />

    <asp:TemplateColumn HeaderText="Telephone">
        <asp:Label ID="lblPhone"
                  Text='<%# DataBinder.Eval(Container.DataItem, "Phone") %>'
                  Runat="server" />


The remainder of the code above completes the layout of our datagrid.

Next is our code-behind file where all the work gets done. Much of the code is the usual database access code to populate the datagrid. The code immediately below contains the Page_Load event where the grid is first bound to its data, the BindTheGrid() routine to actually accomplish the grid's databinding, the Edit event handler to place the grid in edit mode, and the Cancel event handler to get the grid out of edit mode without performing an update. These are necessary routines for any datagrid being presented, and placed in edit mode.

Please note: In the .aspx page and in both sections of the code-behind file being shown here, the lines displayed in purple constitue code that allows the dropdownlist to have the current country value preselected when the grid is placed in edit mode. This code was contributed by Victor Rubba after this article was originally published. I wish to thank Victor for his contribution.

Imports System
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Configuration
Imports System.Data
Imports System.Data.SqlClient

Public Class DataGridDropDown : Inherits Page

  Protected WithEvents dtgCustomers As System.Web.UI.WebControls.DataGrid
  Protected strCountry As String
  Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    If Not Page.IsPostBack Then
    End If
  End Sub

  Public Sub BindTheGrid()
    Dim objConn As SqlConnection = New SqlConnection(ConfigurationSettings.AppSettings("ConnectionString"))
    Dim cmdCustomers As SqlCommand = New SqlCommand("SELECT Top 10 CustomerID, " _
      & "CompanyName, ContactName, ContactTitle, Country, Phone " _
      & "FROM Customers", objConn)

    cmdCustomers.CommandType = CommandType.Text
    dtgCustomers.DataSource = cmdCustomers.ExecuteReader()
  End Sub

  Sub dtgCustomers_Edit(ByVal Sender As Object, ByVal E As DataGridCommandEventArgs)
    strCountry = CType(E.Item.FindControl("lblCountry"), Label).Text
    dtgCustomers.EditItemIndex = CInt(E.Item.ItemIndex)
  End Sub

  Public Sub dtgCustomers_Cancel(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
    dtgCustomers.EditItemIndex = -1
  End Sub

The last three routines, shown below, contain the code to populate our dropdownlistbox, to update the table, and to preselect the existing country in the dropdownlist. Remember on our aspx page we could not populate the dropdownlistbox, but we could make room for it and call a function that would populate it at runtime? BindTheCountry() is shown first below. BindTheCountry() connects to a database table and executes a reader which is returned to the aspx page as the dropdownlistbox's data source. Normally we would access a codes table containing countries. Since such a table was not easily available to me, I just did a SELECT Distinct Country from the Customer's table to have something with which to populate the dropdownlistbox.

Sub dtgCustomers_Update does the updating of the Customers table with the country value selected from the dropdownlistbox. Notice that we must use the FindControl method to locate the dropdownlist box (ddlCountry) and then get the SelectedItem.Value property to find the actual country selected from the dropdown. We also use the hidden label on the datagrid (mentioned in the aspx file discussion) to obtain the CustomerID column to use as a key field in our WHERE clause for the UPDATE.

  Public Function BindTheCountry()
    Dim objConn As SqlConnection = New SqlConnection(ConfigurationSettings.AppSettings("ConnectionString"))
    Dim cmdCustomers As SqlCommand = New SqlCommand("SELECT Distinct Country FROM Customers", objConn)

    cmdCustomers.CommandType = CommandType.Text
    Return cmdCustomers.ExecuteReader(CommandBehavior.CloseConnection)
  End Function

  Public Sub dtgCustomers_Update(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
    Dim objConn As SqlConnection = New SqlConnection(ConfigurationSettings.AppSettings("ConnectionString"))
    Dim cmdCustomers As SqlCommand
    Dim strCustomerID As String = CType(e.Item.FindControl("lblCustomerID"), Label).Text
    Dim strCountry As String = CType(e.Item.FindControl("ddlCountry"), DropDownList).SelectedItem.Value
    Dim strSql As String

    strSql = "UPDATE Customers SET Country='" & strCountry _
           & "' WHERE CustomerID='" & strCustomerID & "'"
    cmdCustomers = New SqlCommand(strSql, objConn)
    dtgCustomers.EditItemIndex = -1
  End Sub

  Public Sub SetDropDownIndex(ByVal sender As Object, ByVal e As System.EventArgs)
    Dim ed As System.Web.UI.WebControls.DropDownList
    ed = sender
    ed.SelectedIndex = ed.Items.IndexOf(ed.Items.FindByText(strCountry))
  End Sub

End Class

A fair amount of code has been presented, but I believe if you will run the demo program several times to see how the editing works in the grid, and then compare what you see to the various sections of code, you will come away with an understanding of how the process works.

Once again, thanks to Victor Rubba for his code contributions (listed in purple) for this article.

You may run the program here.
you may download the code here.


  • precipitant
  • precipitant
  • 2006年06月26日 11:05
  • 2944


下拉列表框-dropdownlistbox、图形下拉列表框-dropdownpicturelistbox 【属性】 下拉列表框提供了37个属性,图形下拉列表框除了这37个属性外,还有5个专门与图形...
  • u012369435
  • u012369435
  • 2014年07月03日 11:16
  • 1951

dropdownlistbox 对text属性赋值为空字串后, 显示不更新

ddlb_1.text="" 不论ddlb_1的Item中
  • zbguohua
  • zbguohua
  • 2014年10月20日 16:15
  • 750

Creating a Scrollable DataGrid...

Place a DataGrid, or any other control or set of controls, within a scrollable region on your .NET w...
  • hiyaolee
  • hiyaolee
  • 2004年10月06日 20:22
  • 725 简析

Android.mk是Android下的编译文件,当你执行mm(用于编译Android代码的命令,当执行 source build/envsetup.sh会生成该命令,可以在build下面查看,其中b...
  • 2016年02月22日 21:52
  • 594


Game Prediction Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9689  ...
  • u013343013
  • u013343013
  • 2014年12月06日 01:34
  • 762


string namedeclare my_cur cursor forselect djmc from sys_djlb using sqlca;open my_cur; fetch my_cur ...
  • zbssoft
  • zbssoft
  • 2010年06月02日 10:41
  • 518


string ls_temp declare readdate dynamic cursor for sqlsa; string ls_sql="select ROLENAME from ...
  • xiaokaibupabupa
  • xiaokaibupabupa
  • 2014年03月01日 15:06
  • 327

drop tablespace XXX including contents and datafiles cascade constraints数据文件无法删除

drop materialized view scott.mv_test_INFO PRESERVE TABLE; 删除内容和数据文件,并删除该表空间关联的主外键等约束。 注意,删除表空间时,在wi...
  • Just2005
  • Just2005
  • 2012年10月17日 15:37
  • 2180

杭电 2057 A+B Again(睡前一水--16进制控制)

A + B Again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To...
  • u013634213
  • u013634213
  • 2014年09月05日 19:51
  • 903
您举报文章:Including a DropDownListBox in an Editable DataGrid...