我已经通过复制粘贴从下面的链接创建了一个批量可编辑的gridview Web用户控件(BulkEditGridView.ascx
),我没有包含任何外部代码:
http://blogs.msdn.com/b/mattdotson/archive/2005/11/09/real-world-gridview-bulk-editing.aspx
我将BulkEditGridView控件添加到另一个Web用户控件OrderDetailGridView.ascx
并将数据源添加到BulkEditGridView
我要做的是在BulkEditGridView中有一个相互依赖的下拉列表和2个文本框。 (请参阅OrderDetailGridView.ascx源代码)当下拉列表更改时,文本框保持不变,单击保存按钮后,相应的值将更新并在文本框中可见。
但是我要做的是当下拉列表更改时,在单击保存按钮之前,我想在文本框中看到相应的值,然后可以使用保存按钮进行保存。
我尝试设置autpostback = true和ddl_MaterialCode_SelectedIndexChanged事件来更改文本框,但是保存按钮不起作用,
我试图放一个updatepanel,再次相同,保存按钮不起作用。
以下是我的代码的源代码,其中保存按钮可用于单击保存后更新文本框的位置。
BulkEditGridView.ascx源代码(我自己没有添加任何东西,只是复制粘贴):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Exportal.Controls
{
public partial class BulkEditGridView : System.Web.UI.WebControls.GridView
{
private List<int> dirtyRows = new List<int>();
[IDReferenceProperty(typeof(Control))]
public string SaveButtonID
{
get
{
string val = (string)this.ViewState["SaveButtonID"];
if (val == null)
{
return string.Empty;
}
return val;
}
set
{
this.ViewState["SaveButtonID"] = value;
}
}
protected override GridViewRow CreateRow(int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState)
{
return base.CreateRow(rowIndex, dataSourceIndex, rowType, rowState | DataControlRowState.Edit);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//Attach an event handler to the save button.
if (false == string.IsNullOrEmpty(this.SaveButtonID))
{
Control btn = RecursiveFindControl(this.NamingContainer, this.SaveButtonID);
if (null != btn)
{
if (btn is Button)
{
((Button)btn).Click += new EventHandler(SaveClicked);
}
}
}
}
private void SaveClicked(object sender, EventArgs e)
{
this.Save();
this.DataBind();
}
protected override void InitializeRow(GridViewRow row, DataControlField[] fields)
{
base.InitializeRow(row, fields);
foreach (DataControlFieldCell cell in row.Cells)
{
if (cell.Controls.Count > 0)
{
AddChangedHandlers(cell.Controls);
}
}
}
private void AddChangedHandlers(ControlCollection controls)
{
foreach (Control ctrl in controls)
{
if (ctrl is TextBox)
{
((TextBox)ctrl).TextChanged += new EventHandler(this.HandleRowChanged);
}
else if (ctrl is CheckBox)
{
((CheckBox)ctrl).CheckedChanged += new EventHandler(this.HandleRowChanged);
}
else if (ctrl is DropDownList)
{
((DropDownList)ctrl).SelectedIndexChanged += new EventHandler(this.HandleRowChanged);
}
}
}
void HandleRowChanged(object sender, EventArgs args)
{
GridViewRow row = ((Control)sender).NamingContainer as GridViewRow;
if (null != row && !dirtyRows.Contains(row.RowIndex))
{
dirtyRows.Add(row.RowIndex);
}
}
public void Save()
{
foreach (int row in dirtyRows)
{
this.UpdateRow(row, false);
}
dirtyRows.Clear();
}
private Control RecursiveFindControl(Control namingcontainer, string controlName)
{
Control c = namingcontainer.FindControl(controlName);
if (c != null)
return c;
if (namingcontainer.NamingContainer != null)
return RecursiveFindControl(namingcontainer.NamingContainer, controlName);
return null;
}
}
}
OrderDetailGridView.ascx源代码:
<cc1:BulkEditGridView ID="BulkEditGridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="RowNo" DataSourceID="SqlDataSource1" SaveButtonID="btn_Kaydet">
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
<asp:BoundField DataField="PONumber" HeaderText="PONumber" SortExpression="PONumber" />
<asp:TemplateField HeaderText="MaterialCode" SortExpression="MaterialCode">
<EditItemTemplate>
<asp:DropDownList ID="ddl_MaterialCode" runat="server" DataSourceID="SqlDataSource2"
DataTextField="MaterialCode" DataValueField="MaterialCode" SelectedValue='<%# Bind("MaterialCode") %>'
OnSelectedIndexChanged="ddl_MaterialCode_SelectedIndexChanged" >
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="MaterialDescription" SortExpression="MaterialDescription">
<EditItemTemplate>
<asp:TextBox ID="txt_MaterialDescription" runat="server" Text='<%# Bind("MaterialDescription") %>'
Enabled="false"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="MaterialCategory" SortExpression="MaterialCategory">
<EditItemTemplate>
<asp:TextBox ID="txt_MaterialCategory" runat="server" Text='<%# Bind("MaterialCategory") %>'
Enabled="false"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="UnitOfMeasure" HeaderText="UnitOfMeasure" SortExpression="UnitOfMeasure" />
<asp:BoundField DataField="Quantity" HeaderText="Quantity" SortExpression="Quantity" />
<asp:BoundField DataField="ContainerType" HeaderText="ContainerType" SortExpression="ContainerType" />
<asp:BoundField DataField="LoadingDate" HeaderText="LoadingDate" SortExpression="LoadingDate" />
</Columns>
</cc1:BulkEditGridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:MyDbConn %>"
DeleteCommand="DELETE FROM [OrderDetail] WHERE [RowNo] = @RowNo" InsertCommand="INSERT INTO [OrderDetail] ([FileNo], [PONumber], [MaterialCode], [MaterialDescription], [MaterialCategory], [UnitOfMeasure], [Quantity], [ContainerType], [LoadingDate]) VALUES (@FileNo, @PONumber, @MaterialCode, @MaterialDescription, @MaterialCategory, @UnitOfMeasure, @Quantity, @ContainerType, @LoadingDate)"
SelectCommand="SELECT * FROM [OrderDetail]" UpdateCommand="UPDATE [OrderDetail] SET [FileNo] = @FileNo, [PONumber] = @PONumber, [MaterialCode] = @MaterialCode, [MaterialDescription] = @MaterialDescription, [MaterialCategory] = @MaterialCategory, [UnitOfMeasure] = @UnitOfMeasure, [Quantity] = @Quantity, [ContainerType] = @ContainerType, [LoadingDate] = @LoadingDate WHERE [RowNo] = @RowNo">
<DeleteParameters>
<asp:Parameter Name="RowNo" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="FileNo" Type="Int32" />
<asp:Parameter Name="PONumber" Type="String" />
<asp:Parameter Name="MaterialCode" Type="String" />
<asp:Parameter Name="MaterialDescription" Type="String" />
<asp:Parameter Name="MaterialCategory" Type="String" />
<asp:Parameter Name="UnitOfMeasure" Type="String" />
<asp:Parameter Name="Quantity" Type="Int32" />
<asp:Parameter Name="ContainerType" Type="String" />
<asp:Parameter Name="LoadingDate" Type="String" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="FileNo" Type="Int32" />
<asp:Parameter Name="PONumber" Type="String" />
<asp:Parameter Name="MaterialCode" Type="String" />
<asp:Parameter Name="MaterialDescription" Type="String" />
<asp:Parameter Name="MaterialCategory" Type="String" />
<asp:Parameter Name="UnitOfMeasure" Type="String" />
<asp:Parameter Name="Quantity" Type="Int32" />
<asp:Parameter Name="ContainerType" Type="String" />
<asp:Parameter Name="LoadingDate" Type="String" />
<asp:Parameter Name="RowNo" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:MyDbConn %>"
SelectCommand="SELECT [MaterialCode] FROM [Materials]"></asp:SqlDataSource>
<asp:Button ID="btn_Kaydet" runat="server" Text="Save" />
OrderDetailGridView.ascx.cs源代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using SOrderDetailData;
using System.Data;
namespace Exportal.Controls
{
public partial class OrderDetailGridView : System.Web.UI.UserControl
{
protected void ddl_MaterialCode_SelectedIndexChanged(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt = OrderDetailData.GetMaterials();
DropDownList ddl_MaterialCode = (DropDownList)sender;
GridViewRow r = (GridViewRow)ddl_MaterialCode.Parent.Parent;
TextBox txt_MaterialDescription = (TextBox)r.FindControl("txt_MaterialDescription");
TextBox txt_MaterialCategory = (TextBox)r.FindControl("txt_MaterialCategory");
txt_MaterialDescription.Text = dt.Rows[ddl_MaterialCode.SelectedIndex]["MaterialDescription"].ToString();
txt_MaterialCategory.Text = dt.Rows[ddl_MaterialCode.SelectedIndex]["MaterialCategory"].ToString();
}
}
}
答案 0 :(得分:1)
您可能需要保留List<int> dirtyRows
,以便它可以在帖子中存活。我建议使用Cache
或Session
,但请查看此MSDN文章Nine Options for Managing Persistent User State in Your ASP.NET Application以获取所有可用选项。
答案 1 :(得分:1)
你应该尝试两件事: 在下面的代码上加上一个断点并进行调试。检查应用是否已达到此btn ...
if (null != btn) {
if (btn is Button) {
((Button)btn).Click += new EventHandler(SaveClicked);
}
}
验证完毕后,您应该将此按钮添加到脚本管理器
if (null != btn) {
if (btn is Button) {
((Button)btn).Click += new EventHandler(SaveClicked);
ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(btn);
}
}
此控件是否以某种方式位于更新面板内(也许您的母版页有所有内容的更新面板)?
答案 2 :(得分:1)
如果您要做的只是使用下拉列表中的选定值填充文本框,我建议使用jquery ......
$('.dropdownclass').change(function() {
$(this).closest('tr').find('.textboxclass').val($(this).val());
});
然后你不需要做额外的回发,希望你的按钮点击能够正常工作。
答案 3 :(得分:1)
如果您要做的只是使用下拉列表中的选定值填充文本框,我还建议像以前写过的人那样写jquery ...
但是,如果您需要在下拉列表更改时执行更多操作...您需要使用网格的RowCommand事件。 这可能会有助RowCommand
短篇小说:
如果你在网格的每一行都有多个命令,那么myGrid_RowCommand函数应该如下所示
void myGrid_RowCommand(Object sender, GridViewCommandEventArgs e) {
if(e.CommandName=="ddlChanged")
{// Do something
}
if(e.CommandName == "ddl2Changed")
{// Do something else
}
...
}