Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save button does not work, when Update Panel is used

I have created a bulk editable gridview web user control (BulkEditGridView.ascx) from the below link by just copy pasting, I did not include any external code:

http://blogs.msdn.com/b/mattdotson/archive/2005/11/09/real-world-gridview-bulk-editing.aspx

I added BulkEditGridView control into another web user control OrderDetailGridView.ascx and add datasource to BulkEditGridView

What I am tring to do is to have an interdependent dropdownlist and 2 textboxes inside my BulkEditGridView. (see OrderDetailGridView.ascx source code) At the moment when dropdownlist changes, textboxes remains unchanged, after save button is clicked, the corresponding values are updated and visible in textboxes.

However what I want to do is when dropdownlist changes, before clicking save button, I want to see corresponding values inside the textboxes, and then be able to save with save button.

I tried to set autpostback=true and ddl_MaterialCode_SelectedIndexChanged event to change the textboxes, but then save button does not work,

I tried to put an updatepanel, again the same, save button did not work.

Below are the source codes of my code in which save button works where textboxes updated after save is clicked.

BulkEditGridView.ascx source code (I did not add anything myself, just copy paste):

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 source code:

<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 source code

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();


        }
    }
}
like image 628
HOY Avatar asked Oct 07 '22 00:10

HOY


1 Answers

You will probably need to persist List<int> dirtyRows so that it can survive the post back. I would recommend either the Cache or Session, however check out this MSDN article Nine Options for Managing Persistent User State in Your ASP.NET Application for all of the options available.

like image 157
Aquila Sands Avatar answered Oct 13 '22 11:10

Aquila Sands