创建 ASP.NET GridView 自定义字段,类型为 DropDownList






4.19/5 (18投票s)
有时您需要在 GridView 中使用 DropDownList,以便显示字段的文本并将值保存到数据库。在这里,我们扩展了“BoundField”类,并添加了功能以创建“DropDownList”类型的列。
引言
有时,您需要在 GridView
中使用 DropDownList
,以便显示字段的文本并将值保存到数据库。在这里,我们扩展了“BoundField
”类,并添加了功能以创建“DropDownList
”类型的列。
例如,在此图片中,您可以看到两个表,Customer(客户)和 Category(类别)。
假设您需要使用 GridView
编辑 Customer 表的内容,并通过“DropDownList
”选择“客户类别”。您希望在网格中看到 CategoryName
,但将 CategoryID
保存到数据库,如图所示
背景
您有两种解决方案
- 第一种解决方案是创建类型为
DropDownList
的 Template 列。 - 第二种解决方案是创建一个带有“
DropDownList
”编辑器的新的列类型,并为其引入一个“实体名称”。在这里,我们扩展了“BoundField
”类,并添加了功能以创建“DropDownList
”类型的列。
使用代码
现在,您可以轻松地使用此列类型,例如
<CustomFields:ComboBoxField BusinessObjectName="CategoryBO"
DataTextField="CategoryName" DataValueField="CategoryID"
SelectMethod="GetCategories" DataField="Category"
IDDataField="CategoryID" SortExpression="Category"
HeaderText="Category"></CustomFields:ComboBoxField>
为此,您应该将主表与引用表连接起来,并创建一个包含组合框字段的文本和值的视图
CREATE VIEW vCustomers AS
SELECT dbo.Customers.CustomerID, dbo.Customers.FirstName, dbo.Customers.LastName,
dbo.Customers.CategoryID, dbo.Category.CategoryName AS Category FROM
dbo.Customers INNER JOIN
dbo.Category ON dbo.Customers.CategoryID = dbo.Category.CategoryID
并且,在 GridView
中创建文本和值列,并将值列的“可见性”设置为 False
<CustomFields:ComboBoxField BusinessObjectName="CategoryBO"
DataTextField="CategoryName" DataValueField="CategoryID"
SelectMethod="GetCategories" DataField="Category"
IDDataField="CategoryID" SortExpression="Category"
HeaderText="Category"></CustomFields:ComboBoxField>
<asp:BoundField DataField="CategoryID"
HeaderText="CategoryID"
SortExpression="CategoryID"
Visible="False"/>
第一步是创建一个从 BoundField
类继承的新类
public class ComboBoxField:BoundField
{
. . .
第二步是更改 ExtractValuesFromCell
方法,以获取用于编辑编辑模式下单元格的 DropDownList
控件
public override void ExtractValuesFromCell(IOrderedDictionary dictionary,
DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly)
{
. . . .
if (cell.Controls.Count > 0)
{
// Get column editor of type DropDownList of current cell
control = cell.Controls[0];
DropDownList box = control as DropDownList;
if ((box != null) && (includeReadOnly || box.Enabled))
{
obj2 = box.Text;
if (obj2 != null)
{
// extract value from DropDownList
ListItem itm = box.Items.FindByValue(obj2.ToString());
obj3 = itm.Text;
}
}
}
if (obj2 != null)
{
if (dictionary.Contains(dataField))
{
dictionary[dataField] = obj2;
}
else
{
//put both text and value into the dictionary
dictionary.Add(dataField, obj3);
dictionary.Add(this.IDDataField, obj2);
第三步是更改 InitializeDataCell
方法,以在编辑单元格中创建 DropDownList
控件。
protected override void InitializeDataCell(DataControlFieldCell cell,
DataControlRowState rowState)
{
Control child = null;
Control control2 = null;
if ((((rowState & DataControlRowState.Edit) != DataControlRowState.Normal) &&
!this.ReadOnly) || ((rowState & DataControlRowState.Insert)
!= DataControlRowState.Normal))
{
// If data cell is in edit mode, create DropDownList editor for this cell
// and set data properties.
DropDownList box = new DropDownList();
box.DataSource =this.GetDataSource();
box.DataMember = this.BusinessObjectName;
box.DataTextField = this.DataTextField;
box.DataValueField = this.DataValueField;
box.DataBind();
.
.
.
protected override void OnDataBindField(object sender, EventArgs e)
{
Control control = (Control)sender;
Control namingContainer = control.NamingContainer;
object dataValue = this.GetValue(namingContainer);
bool encode = (this.SupportsHtmlEncode && this.HtmlEncode) && (control is TableCell);
string str = this.FormatDataValue(dataValue, encode);
if (control is TableCell)
{
if (str.Length == 0)
{
str = " ";
}
((TableCell)control).Text = str;
}
else
{
//If data cell is in edit mode, set selected value of DropDownList
if (dataValue != null)
{
ListItem itm = ((DropDownList)control).Items.FindByText(dataValue.ToString());
((DropDownList)control).Text = itm.Value;
}