分享
 
 
 

Including a DropDownListBox in an Editable DataGrid...

王朝c#·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

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" %>

<html>

<head>

<title>DataGrid with a DropDownListBox</title>

</head>

<body>

<form runat="server" ID="Form1">

<h3>DataGrid with a DropDownListBox</h3>

<asp:DataGrid ID="dtgCustomers" runat="server"

AutoGenerateColumns=False

HeaderStyle-BackColor="IndianRed"

HeaderStyle-Font-Bold="True"

HeaderStyle-Font-Name="Verdana"

HeaderStyle-Font-Size="12px"

HeaderStyle-ForeColor="White"

ItemStyle-BackColor=Gainsboro

ItemStyle-Font-Name="verdana"

ItemStyle-Font-Size="12px"

OnCancelCommand="dtgCustomers_Cancel"

OnEditCommand="dtgCustomers_Edit"

OnUpdateCommand="dtgCustomers_Update"

Width="75%">

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.

<Columns>

<asp:EditCommandColumn EditText="Edit"

CancelText="Cancel"

UpdateText="Update"

ItemStyle-Width="100px"

HeaderText="Commands" />

<asp:TemplateColumn HeaderText="Company Name">

<ItemTemplate>

<asp:Label ID="lblCompanyName"

Text='<%# DataBinder.Eval(Container.DataItem, "CompanyName") %>'

Runat="server" />

</ItemTemplate>

</asp:TemplateColumn>

<asp:TemplateColumn HeaderText="Contact Name">

<ItemTemplate>

<asp:Label ID="lblContactName"

Text='<%# DataBinder.Eval(Container.DataItem, "ContactName") %>'

Runat="server" />

</ItemTemplate>

</asp:TemplateColumn>

<asp:TemplateColumn HeaderText="Contact Title">

<ItemTemplate>

<asp:Label ID="lblContactTitle"

Text='<%# DataBinder.Eval(Container.DataItem, "ContactTitle") %>'

Runat="server" />

</ItemTemplate>

</asp:TemplateColumn>

<asp:TemplateColumn HeaderText="Country">

<ItemTemplate>

<asp:Label ID="lblCountry"

Text='<%# DataBinder.Eval(Container.DataItem, "Country") %>'

Runat="server" />

</ItemTemplate>

<EditItemTemplate>

<asp:Label runat="server"

id="lblCustomerID"

Visible="False"

Text='<%# DataBinder.Eval(Container.DataItem, "CustomerID") %>'/>

<asp:Label ID="lblTempState"

Text='<%# DataBinder.Eval(Container.DataItem, "Country") %>'

Runat="server" />

<asp:DropDownList id="ddlCountry"

DataSource="<%# BindTheCountry() %>"

OnPreRender="SetDropDownIndex"

DataTextField="Country"

DataValueField="Country"

runat="server" />

</EditItemTemplate>

</asp:TemplateColumn>

<asp:TemplateColumn HeaderText="Telephone">

<ItemTemplate>

<asp:Label ID="lblPhone"

Text='<%# DataBinder.Eval(Container.DataItem, "Phone") %>'

Runat="server" />

</ItemTemplate>

</asp:TemplateColumn>

</Columns>

</asp:DataGrid>

</form>

</body>

</html>

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

BindTheGrid()

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

objConn.Open()

dtgCustomers.DataSource = cmdCustomers.ExecuteReader()

dtgCustomers.DataBind()

objConn.Close()

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)

BindTheGrid()

End Sub

Public Sub dtgCustomers_Cancel(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)

dtgCustomers.EditItemIndex = -1

BindTheGrid()

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

objConn.Open()

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)

objConn.Open()

cmdCustomers.ExecuteReader(CommandBehavior.CloseConnection)

dtgCustomers.EditItemIndex = -1

BindTheGrid()

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.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有