是否可以将 List 绑定到 GridView 并使其编辑功能正常工作?
您可以绑定到 ObjectDataSource,但您需要在后端实现一些方法并将它们连接到您的数据源来处理更新,因为数据源本身不知道如何保存数据。
这里有一篇 MSDN 文章 对此进行了描述。
我不知道这是否正是您正在寻找的,但这就是我所做的,并且它比我找到的任何其他答案都更好。我从其他答案中汲取了所有最好的部分。 我使用的方法允许您编辑一行,仅将所需的可编辑字段转换为文本框,以及可以选择的项目的下拉列表,然后为所选项目保存 ID。
数据库表
CREATE TABLE [dbo].[tblPerson] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[FirstName] VARCHAR (50) NULL,
[Surname] VARCHAR (50) NULL,
[DateOfBirth] DATETIME NULL,
[TypeID] INT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE TABLE [dbo].[tblType] (
[TypeId] INT IDENTITY (1, 1) NOT NULL,
[Type] VARCHAR (50) NULL,
PRIMARY KEY CLUSTERED ([TypeId] ASC)
);
GridView显示的视图
CREATE VIEW [dbo].[vwPeople]
AS SELECT p.Id,
p.FirstName,
p.Surname,
p.DateOfBirth,
t.[Type]
FROM [tblPerson] AS p
LEFT OUTER JOIN [tblType] AS t ON p.TypeID = t.TypeId
默认.aspx位
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="Id" OnRowEditing="GridView1_RowEditing"
OnRowUpdating="GridView1_RowUpdating" OnRowCancelingEdit="GridView1_RowCancelingEdit" OnRowDataBound="GridView1_RowDataBound" Width="60%">
<Columns>
<asp:TemplateField HeaderStyle-Width="80px" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button ID="btnEdit" runat="server" Text="edit" CommandName="Edit" CssClass-="button" />
</ItemTemplate>
<EditItemTemplate>
<asp:Button ID="btnUpdate" runat="server" Text="update" CommandName="Update" CssClass-="buttonupdate" />
<asp:Button ID="btnCancel" runat="server" Text="cancel" CommandName="Cancel" CssClass-="buttoncancel" />
</EditItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Id" HeaderText="Id" ReadOnly="True" SortExpression="Id" HeaderStyle-Width="40px" />
<asp:TemplateField HeaderText="FirstName" SortExpression="FirstName">
<EditItemTemplate>
<asp:TextBox ID="txtFirstName" runat="server" Text='<%# Bind("FirstName") %>' Width="150px"></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblFirstName" runat="server" Text='<%# Bind("FirstName") %>' Width="150px"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Surname" SortExpression="Surname">
<EditItemTemplate>
<asp:TextBox ID="txtSurname" runat="server" Text='<%# Bind("Surname") %>' Width="150px"></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblSurname" runat="server" Text='<%# Bind("Surname") %>' Width="150px"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="DateOfBirth" SortExpression="DateOfBirth" HeaderStyle-Width="20%">
<EditItemTemplate>
<asp:TextBox ID="txtDateOfBirth" runat="server" Text='<%# Bind("DateOfBirth", "{0:d}") %>' Width="100px"></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblDateOfBirth" runat="server" Text='<%# Bind("DateOfBirth", "{0:d}") %>' Width="100px"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Type" SortExpression="Type">
<EditItemTemplate>
<asp:DropDownList ID="ddlType" runat="server">
</asp:DropDownList>
<asp:Label ID="lblType" runat="server" Text='<%# Bind("Type") %>' Visible="false"></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblType" runat="server" Text='<%# Bind("Type") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
默认.aspx.cs 位
namespace GridViewTestApp1
{
public partial class _Default : Page
{
//Connection String from web.config File
string cs = ConfigurationManager.ConnectionStrings["GridViewTestDbConnectionString"].ConnectionString;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ShowData();
}
}
//ShowData method for Displaying Data in Gridview
protected void ShowData()
{
DataTable dt = new DataTable();
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
using (SqlDataAdapter adapt = new SqlDataAdapter("Select ID, FirstName, Surname, DateOfBirth, Type from vwPeople", con))
{
adapt.Fill(dt);
if (dt.Rows.Count > 0)
{
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
con.Close();
}
}
protected DataTable GetData(string sSQL)
{
DataTable dt = new DataTable();
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
using (SqlDataAdapter da = new SqlDataAdapter(sSQL, con))
{
da.Fill(dt);
}
con.Close();
}
return dt;
}
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
// NewEditIndex used to determine index of row being edited
GridView1.EditIndex = e.NewEditIndex;
ShowData();
}
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
CDBFunctions DBFunctions = new CDBFunctions();
GridViewRow gvr = (GridViewRow)GridView1.Rows[e.RowIndex];
//Finding the controls from Gridview for the row which is going to update
// ID can be retrieved from the cell, as it is a bound field
// Ediable fields are all template fields so need to use FindControl to retrive them
string sID = gvr.Cells[1].Text;
TextBox txtFirstName = gvr.FindControl("txtFirstName") as TextBox;
TextBox txtSurname = gvr.FindControl("txtSurname") as TextBox;
TextBox txtDateOfBirth = gvr.FindControl("txtDateOfBirth") as TextBox;
DropDownList ddlType = gvr.FindControl("ddlType") as DropDownList;
string sDateOfBirth = txtDateOfBirth.Text;
DateTime dtDateOfBirth;
DateTime.TryParse(sDateOfBirth, out dtDateOfBirth);
// Get DropDownList value
string sTypeID = ddlType.SelectedValue;
int iTypeID;
int.TryParse(sTypeID, out iTypeID);
string sSQL = string.Format("UPDATE tblPerson set FirstName = '{0}', Surname = '{1}', DateOfBirth = '{2}', TypeID = {3} WHERE ID = {4}", txtFirstName.Text, txtSurname.Text, DBFunctions.ConvertDateUSFormat(dtDateOfBirth), iTypeID, Convert.ToInt32(sID));
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
//updating the record
using (SqlCommand cmd = new SqlCommand(sSQL, con))
{
cmd.ExecuteNonQuery();
}
con.Close();
}
//Setting the EditIndex property to -1 to cancel the Edit mode in Gridview
GridView1.EditIndex = -1;
//Call ShowData method for displaying updated data
ShowData();
}
protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
//Setting the EditIndex property to -1 to cancel the Edit mode in Gridview
GridView1.EditIndex = -1;
ShowData();
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
// After the data has been bound we need to populate the Type drop down box
// and selet the item that matches that row.
// Unfortunately we cannot just databind the item in the drop down box or it would be a lot easier
if (GridView1.EditIndex != -1)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (e.Row.RowIndex == GridView1.EditIndex)
{
//Find the DropDownList in the Row.
DropDownList ddlType = (e.Row.FindControl("ddlType") as DropDownList);
ddlType.DataSource = GetData("SELECT DISTINCT TypeID, Type FROM tblType");
ddlType.DataTextField = "Type";
ddlType.DataValueField = "TypeID";
ddlType.DataBind();
//Add Default Item in the DropDownList.
ddlType.Items.Insert(0, new ListItem(""));
//Select the Country of Customer in DropDownList.
string sType = (e.Row.FindControl("lblType") as Label).Text;
//ddlType.Items.FindByValue(sType).Selected = true;
ddlType.Items.FindByText(sType).Selected = true;
}
}
}
}
}
}
CSS位
.button {
background-color: transparent;
border: none;
cursor: pointer;
text-decoration: none;
padding: 0px;
}
.buttonupdate {
background-color: transparent;
border: none;
cursor: pointer;
text-decoration: none;
padding: 0px;
color: green;
}
.buttoncancel {
background-color: transparent;
border: none;
cursor: pointer;
text-decoration: none;
padding: 0px;
color: red;
}
将日期时间转换为美国格式字符串函数
public string ConvertDateTimeUSFormat(DateTime dte)
{
string sNewDateString = string.Empty;
try
{
sNewDateString = dte.Month.ToString("00") + "/" + dte.Day.ToString("00") + "/" + dte.Year.ToString() + " " + dte.Hour.ToString("00") + ":" + dte.Minute.ToString("00") + ":" + dte.Second.ToString("00");
}
catch
{
sNewDateString = "1900-01-01";
}
return sNewDateString;
}
希望这有帮助。