EditItemTemplate 中的 DropDownList 不更新 table
DropDownList in EditIemTemplate does not update table
所以我有一个显示借出信息的 GridView
,我的 Loans
table 有 Laptop
、User
、[=16= 的 ID ], 等等
当我在 GridView
上显示时,我使用姓名而不是 ID 号码。
我的问题是,当我在 edititemtemplate 中放置一个下拉列表时,如下所示,它不会更新我的 table 并且出现以下错误我希望能够更新我的贷款 table适当的信息:
Cannot insert the value NULL into column 'Laptop_ID', table 'itassetmgmt.dbo.Loans'; column does not allow nulls. UPDATE fails.
The statement has been terminated.
贷款Table包括:
Loan_ID
Date_Loaned
Date_Returned
Sign_Off
Laptop_ID
User_ID
Dept_ID
Location_ID
ASPX:
<asp:TemplateField HeaderText="Laptop_Name" SortExpression="Laptop_Name">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" SelectedValue ='<%# Bind("Laptop_Name") %>' runat="server" DataSourceID="editLPID" DataTextField="Laptop_Name" DataValueField="Laptop_Name">
</asp:DropDownList>
<asp:SqlDataSource ID="editLPID" runat="server" ConnectionString="<%$ ConnectionStrings:itassetmgmtConnectionString1 %>" SelectCommand="SELECT [Laptop_ID], [Laptop_Name] FROM [Laptops]"></asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("Laptop_Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name" SortExpression="Name">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList2" runat="server" SelectedValue='<%# Bind("Name") %>' DataSourceID="editUID" DataTextField="Name" DataValueField="Name">
</asp:DropDownList>
<asp:SqlDataSource ID="editUID" runat="server" ConnectionString="<%$ ConnectionStrings:itassetmgmtConnectionString1 %>" SelectCommand="SELECT User_ID, Firstname +' '+ Lastname AS Name FROM Users"></asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Department" SortExpression="Department">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList3" runat="server" SelectedValue='<%# Bind("Department") %>' DataSourceID="editDID" DataTextField="Department" DataValueField="Department">
</asp:DropDownList>
<asp:SqlDataSource ID="editDID" runat="server" ConnectionString="<%$ ConnectionStrings:itassetmgmtConnectionString1 %>" SelectCommand="SELECT * FROM [Departments]"></asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Bind("Department") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Location_Name" SortExpression="Location_Name">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList4" runat="server" SelectedValue='<%# Bind("Location_Name") %>' DataSourceID="editLID" DataTextField="Location_Name" DataValueField="Location_Name">
</asp:DropDownList>
<asp:SqlDataSource ID="editLID" runat="server" ConnectionString="<%$ ConnectionStrings:itassetmgmtConnectionString1 %>" SelectCommand="SELECT * FROM [Locations]"></asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label4" runat="server" Text='<%# Bind("Location_Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
编辑:
我知道这可能是因为 DropDownList 的 DataValueField 没有设置为 table 中相应的 ID#,但是当我更改 DataValueField 时,它给了我一堆错误。有什么建议吗?
我的更新命令:UpdateCommand="UPDATE [Loans] SET [Date_Loaned] = @Date_Loaned, [Date_Returned] = @Date_Returned, [Sign_Off] = @Sign_Off, [Laptop_ID] = @Laptop_ID, [User_ID] = @User_ID, [Dept_ID] = @Dept_ID, [Location_ID] = @Location_ID WHERE [Loan_ID] = @original_Loan_ID"
您可以使用 Gridview 的 OnRowDataBound 事件:
protected void MyGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if(e.Row.RowState == DataControlRowState.Edit)
{
DropDownList DropDownList1 = e.Row.FindControl("DropDownList1") as DropDownList1;
Label Laptop_Name = e.Row.FindControl("Laptop_Name") as Label;
//one option
DropDownList1.SelectedValue = Laptop_Name.Text;
//however for this option to work, when dropdownlist1 is binded data, its DataValueField should be set to "Laptop_Name"
//second option with foreach
foreach(ListItem item in DropDownList1.Items)
{
if(item.Text == Laptop_Name.Text)
item.Selected = true; //not sure if the syntax is correct
}
}
}
}
您需要按如下方式更改 DropDownList1 定义:
<asp:DropDownList ID="DropDownList1" SelectedValue ='<%# Bind("Laptop_Id") %>' runat="server" DataSourceID="editLPID" DataTextField="Laptop_Name" DataValueField="Laptop_Id">
在 Gridview 中,从网格的可显示部分中取出所有 ID。不需要显示它们,但是它们必须是 gridview 数据源的一部分才能绑定它们
然后在 ItemTemplate
(我只显示用户模板)DataTextField
和 DataValueField
来自 DropDownList 数据源 BUT SelectedValue
属性 绑定到 Gridview User_ID :
<asp:TemplateField>
<ItemTemplate>
<asp:DropDownList ID="DropDownList2Disabled" runat="server" DataSourceID="SqlDataSource3"
Enabled="False"
DataTextField="Name"
DataValueField="User_ID"
SelectedValue='<%# Eval("User_ID") %>'>
</asp:DropDownList>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList2" runat="server" DataSourceID="SqlDataSource3"
DataTextField="Name"
DataValueField="User_ID"
SelectedValue='<%# Bind("User_ID") %>'>
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
我在 ItemTemplate
和 EditItemTemplate
中都使用 DDL,一个禁用,另一个启用。如果您愿意,可以在项目 table 中使用标签,但这需要更多工作,因为用户名不是 gridview 的一部分。
如果您可以控制 gridview sql 并且可以将用户名添加到数据集(例如 UserName),那么您可以将 ItemTemplate 标签绑定到 UserName 并将 EditItemTemplate DropDownList 绑定到 User_ID
编辑:扩展示例:
所以,按照标签的想法,模板看起来像这样:
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="LabelUserName" runat="server" Text='<%# Eval("UserName") %>'>
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList2" runat="server" DataSourceID="SqlDataSource3"
DataTextField="Name"
DataValueField="User_ID"
SelectedValue='<%# Bind("User_ID") %>'>
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
Gridview 数据源 Select(或存储过程)看起来(或包含)如下所示:
Select Loan_ID
, l.Date_Loaned
, l.Date_Returned
, l.Sign_Off
, l.Laptop_ID
, l.User_ID
, u.FirstName + ' ' + u.LastName as UserName
, l.Dept_ID
, d.DepartmentName
, l.Location_ID
, (etc...)
From LoansTable l
Left Join UserTable u on u.User_ID = l.User_ID
Left Join DeptTable d on d.Dept_ID = l.Dept_ID
(etc.)
Order By d.DepartmentName
, l.Date_Loaned
所以这将 return 一个字段集,它为 Gridview 提供足够的用户友好数据以进行干净的显示,以及您作为程序员可能需要在用户与 Gridview 交互时进行更改的 ID .
现在,通过将 ID 添加到 DataKeyNames 属性,ID 可能会也可能不会被添加到 GridView。这将允许在 GridView 回发期间轻松访问代码中的 ID。放置在这里的键不是 GridView 的可显示部分的一部分
EditItemTemplate 中的 DDL 有它自己的数据源,并且有一个简单的 Select:
Select User_ID, FirstName + ' ' + LastName as Name From UserTable
不要混淆来自 2 个不同数据源的重复字段。在 EditItemTemplate 中的 DDL 声明:
<asp:DropDownList ID="DropDownList2" runat="server" DataSourceID="SqlDataSource3"
DataTextField="Name"
DataValueField="User_ID"
SelectedValue='<%# Bind("User_ID") %>'>
</asp:DropDownList>
DataValueField="User_ID"
指的是 DDL 数据源,而 SelectedValue='<%# Bind("User_ID") %>'
是对 GridView 数据源
中的 User_ID
字段的绑定
这里的 Gridview User_ID
字段是来自用户的 "hidden" 但 Gridview 可以用于编辑目的,并且如果您放置它在 DataKeyNames
所以我有一个显示借出信息的 GridView
,我的 Loans
table 有 Laptop
、User
、[=16= 的 ID ], 等等
当我在 GridView
上显示时,我使用姓名而不是 ID 号码。
我的问题是,当我在 edititemtemplate 中放置一个下拉列表时,如下所示,它不会更新我的 table 并且出现以下错误我希望能够更新我的贷款 table适当的信息:
Cannot insert the value NULL into column 'Laptop_ID', table 'itassetmgmt.dbo.Loans'; column does not allow nulls. UPDATE fails. The statement has been terminated.
贷款Table包括: Loan_ID Date_Loaned Date_Returned Sign_Off Laptop_ID User_ID Dept_ID Location_ID
ASPX:
<asp:TemplateField HeaderText="Laptop_Name" SortExpression="Laptop_Name">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" SelectedValue ='<%# Bind("Laptop_Name") %>' runat="server" DataSourceID="editLPID" DataTextField="Laptop_Name" DataValueField="Laptop_Name">
</asp:DropDownList>
<asp:SqlDataSource ID="editLPID" runat="server" ConnectionString="<%$ ConnectionStrings:itassetmgmtConnectionString1 %>" SelectCommand="SELECT [Laptop_ID], [Laptop_Name] FROM [Laptops]"></asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("Laptop_Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name" SortExpression="Name">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList2" runat="server" SelectedValue='<%# Bind("Name") %>' DataSourceID="editUID" DataTextField="Name" DataValueField="Name">
</asp:DropDownList>
<asp:SqlDataSource ID="editUID" runat="server" ConnectionString="<%$ ConnectionStrings:itassetmgmtConnectionString1 %>" SelectCommand="SELECT User_ID, Firstname +' '+ Lastname AS Name FROM Users"></asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Department" SortExpression="Department">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList3" runat="server" SelectedValue='<%# Bind("Department") %>' DataSourceID="editDID" DataTextField="Department" DataValueField="Department">
</asp:DropDownList>
<asp:SqlDataSource ID="editDID" runat="server" ConnectionString="<%$ ConnectionStrings:itassetmgmtConnectionString1 %>" SelectCommand="SELECT * FROM [Departments]"></asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Bind("Department") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Location_Name" SortExpression="Location_Name">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList4" runat="server" SelectedValue='<%# Bind("Location_Name") %>' DataSourceID="editLID" DataTextField="Location_Name" DataValueField="Location_Name">
</asp:DropDownList>
<asp:SqlDataSource ID="editLID" runat="server" ConnectionString="<%$ ConnectionStrings:itassetmgmtConnectionString1 %>" SelectCommand="SELECT * FROM [Locations]"></asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label4" runat="server" Text='<%# Bind("Location_Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
编辑: 我知道这可能是因为 DropDownList 的 DataValueField 没有设置为 table 中相应的 ID#,但是当我更改 DataValueField 时,它给了我一堆错误。有什么建议吗?
我的更新命令:UpdateCommand="UPDATE [Loans] SET [Date_Loaned] = @Date_Loaned, [Date_Returned] = @Date_Returned, [Sign_Off] = @Sign_Off, [Laptop_ID] = @Laptop_ID, [User_ID] = @User_ID, [Dept_ID] = @Dept_ID, [Location_ID] = @Location_ID WHERE [Loan_ID] = @original_Loan_ID"
您可以使用 Gridview 的 OnRowDataBound 事件:
protected void MyGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if(e.Row.RowState == DataControlRowState.Edit)
{
DropDownList DropDownList1 = e.Row.FindControl("DropDownList1") as DropDownList1;
Label Laptop_Name = e.Row.FindControl("Laptop_Name") as Label;
//one option
DropDownList1.SelectedValue = Laptop_Name.Text;
//however for this option to work, when dropdownlist1 is binded data, its DataValueField should be set to "Laptop_Name"
//second option with foreach
foreach(ListItem item in DropDownList1.Items)
{
if(item.Text == Laptop_Name.Text)
item.Selected = true; //not sure if the syntax is correct
}
}
}
}
您需要按如下方式更改 DropDownList1 定义:
<asp:DropDownList ID="DropDownList1" SelectedValue ='<%# Bind("Laptop_Id") %>' runat="server" DataSourceID="editLPID" DataTextField="Laptop_Name" DataValueField="Laptop_Id">
在 Gridview 中,从网格的可显示部分中取出所有 ID。不需要显示它们,但是它们必须是 gridview 数据源的一部分才能绑定它们
然后在 ItemTemplate
(我只显示用户模板)DataTextField
和 DataValueField
来自 DropDownList 数据源 BUT SelectedValue
属性 绑定到 Gridview User_ID :
<asp:TemplateField>
<ItemTemplate>
<asp:DropDownList ID="DropDownList2Disabled" runat="server" DataSourceID="SqlDataSource3"
Enabled="False"
DataTextField="Name"
DataValueField="User_ID"
SelectedValue='<%# Eval("User_ID") %>'>
</asp:DropDownList>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList2" runat="server" DataSourceID="SqlDataSource3"
DataTextField="Name"
DataValueField="User_ID"
SelectedValue='<%# Bind("User_ID") %>'>
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
我在 ItemTemplate
和 EditItemTemplate
中都使用 DDL,一个禁用,另一个启用。如果您愿意,可以在项目 table 中使用标签,但这需要更多工作,因为用户名不是 gridview 的一部分。
如果您可以控制 gridview sql 并且可以将用户名添加到数据集(例如 UserName),那么您可以将 ItemTemplate 标签绑定到 UserName 并将 EditItemTemplate DropDownList 绑定到 User_ID
编辑:扩展示例:
所以,按照标签的想法,模板看起来像这样:
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="LabelUserName" runat="server" Text='<%# Eval("UserName") %>'>
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList2" runat="server" DataSourceID="SqlDataSource3"
DataTextField="Name"
DataValueField="User_ID"
SelectedValue='<%# Bind("User_ID") %>'>
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
Gridview 数据源 Select(或存储过程)看起来(或包含)如下所示:
Select Loan_ID
, l.Date_Loaned
, l.Date_Returned
, l.Sign_Off
, l.Laptop_ID
, l.User_ID
, u.FirstName + ' ' + u.LastName as UserName
, l.Dept_ID
, d.DepartmentName
, l.Location_ID
, (etc...)
From LoansTable l
Left Join UserTable u on u.User_ID = l.User_ID
Left Join DeptTable d on d.Dept_ID = l.Dept_ID
(etc.)
Order By d.DepartmentName
, l.Date_Loaned
所以这将 return 一个字段集,它为 Gridview 提供足够的用户友好数据以进行干净的显示,以及您作为程序员可能需要在用户与 Gridview 交互时进行更改的 ID .
现在,通过将 ID 添加到 DataKeyNames 属性,ID 可能会也可能不会被添加到 GridView。这将允许在 GridView 回发期间轻松访问代码中的 ID。放置在这里的键不是 GridView 的可显示部分的一部分
EditItemTemplate 中的 DDL 有它自己的数据源,并且有一个简单的 Select:
Select User_ID, FirstName + ' ' + LastName as Name From UserTable
不要混淆来自 2 个不同数据源的重复字段。在 EditItemTemplate 中的 DDL 声明:
<asp:DropDownList ID="DropDownList2" runat="server" DataSourceID="SqlDataSource3"
DataTextField="Name"
DataValueField="User_ID"
SelectedValue='<%# Bind("User_ID") %>'>
</asp:DropDownList>
DataValueField="User_ID"
指的是 DDL 数据源,而 SelectedValue='<%# Bind("User_ID") %>'
是对 GridView 数据源
User_ID
字段的绑定
这里的 Gridview User_ID
字段是来自用户的 "hidden" 但 Gridview 可以用于编辑目的,并且如果您放置它在 DataKeyNames