使用“更新面板”时,“保存”按钮不起作用

时间:2012-08-07 10:45:04

标签: c# asp.net ajax gridview updatepanel

我已经通过复制粘贴从下面的链接创建了一个批量可编辑的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();


        }
    }
}

4 个答案:

答案 0 :(得分:1)

您可能需要保留List<int> dirtyRows,以便它可以在帖子中存活。我建议使用CacheSession,但请查看此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

短篇小说:

  1. 将OnRowCommand =“myGrid_RowCommand”添加到网格属性
  2. 将CommandName =“ddlChanged”添加到网格下拉列表的属性中
  3. 如果你在网格的每一行都有多个命令,那么myGrid_RowCommand函数应该如下所示

    void myGrid_RowCommand(Object sender, GridViewCommandEventArgs e)  {    
    if(e.CommandName=="ddlChanged") 
        {// Do something
        } 
    if(e.CommandName == "ddl2Changed")
        {// Do something else
        }
    ...
    }