Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update textbox from 1st UpdatePanel using LinkButton from 2nd UpdatePanel's gridview. Control could not be found

I need to add the LinkButton btnAddRow in UpdatePanel upSectionB but the problem is I'm having this error during load:

A control with ID 'btnAddRow' could not be found for the trigger in UpdatePanel 'upSectionB'.

My simplified aspx

<asp:UpdatePanel ID="upSectionB" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
    <ContentTemplate>
        Request Budget (USD)
        <asp:TextBox ID="txtTotal" runat="server"></asp:TextBox>

    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="btnAddRow" EventName="Click" />
        //Poses problems when I uncomment the trigger above. btnAddRow is a LinkButton inside upSectionC
    </Triggers>
</asp:UpdatePanel>

<asp:UpdatePanel ID="upSectionC" runat="server">
    <ContentTemplate>
        <asp:GridView ID="gvCostBreakdown" runat="server" AutoGenerateColumns="false" ShowFooter="true">
            <Columns>
                <asp:TemplateField HeaderText="Amount">
                    <ItemTemplate>
                        <asp:TextBox ID="txtAmount" runat="server" Text='<%# Eval("BudgetUSD") %>'></asp:TextBox>
                    </ItemTemplate>
                    <FooterTemplate>
                        <asp:TextBox ID="txtAmountTotal" runat="server" Enabled="false"></asp:TextBox>
                    </FooterTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Delete" ItemStyle-HorizontalAlign="Center">
                    <ItemTemplate>
                        <asp:LinkButton ID="btnDeleteRow" runat="server" ToolTip="Delete" OnClick="btnDeleteRow_Click" CommandArgument='<%# Eval("Id","{0}") %>' OnClientClick="">Delete</asp:LinkButton>
                    </ItemTemplate>
                    <FooterTemplate>
                        <asp:LinkButton ID="btnAddRow" runat="server" CausesValidation="true" ValidationGroup="vgAddRow" ToolTip="Add Row" OnClick="btnAddRow_Click">Add Row</asp:LinkButton>
                    </FooterTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
    </ContentTemplate>
</asp:UpdatePanel>
like image 577
Harambe Attack Helicopter Avatar asked Apr 02 '18 04:04

Harambe Attack Helicopter


People also ask

Why doesn't the linkbutton trigger the UpdatePanel to update?

The literal inside the UpdatePanel is only updated when the LinkButton is clicked. This makes for something like this for the first time the page loads: Because the LinkButton is inside the UpdatePanel, you would think hitting it would trigger the UpdatePanel so only the literal control inside the UpdatePanel gets updated.

Why can't I find Button1 in Ajax UpdatePanel trigger?

A control with ID 'Button1' could not be found for the trigger in UpdatePanel. The HTML Markup consists of ASP.Net GridView with 2 LinkButtons placed inside an AJAX UpdatePanel. You will need to import the following namespace.

Why does the click event for the linkbutton result in postback?

When you dynamically generate a LinkButton in code that will be placed inside an UpdatePanel, you’ll experience that the Click event for the LinkButton results in a full postback in stead of the UpdatePanel being triggered. There’s a rather simpel solution to this problem… First, let’s take a look at the scenario.

How to test if GridView is bound in not ispostback condition?

Many sites suggest use of OnRowDataBound or OnDataBinding events but these methods also work only for first time if the GridView is bound in Not IsPostBack condition and hence I came up with this technique. Click events for Buttons for testing Full PostBack and Partial PostBack


2 Answers

The only thing you need to do is trigger the Update of upSectionB when btnAddRow is clicked.

protected void btnAddRow_Click(object sender, EventArgs e)
{
    txtTotal.Text = "new value";

    //update the other updatepanel
    upSectionB.Update();
}

The reason you get that error is because the button is in a GridView Control and therefore not accessible in the scope of the aspx page. If you wanted to do something with the button in the Footer, you need to use FindControl.

LinkButton lb = gvCostBreakdown.FooterRow.FindControl("btnAddRow") as LinkButton;
like image 168
VDWWD Avatar answered Nov 15 '22 13:11

VDWWD


I have the same problem (Reason why this error occurs as your LinkButton is inside GridView which will not be triggered outside the GridView) and fixed it following below steps:

Step 1: Add a RowCommand event in your GridView:

<asp:GridView ID="gvCostBreakdown" OnRowCommand="gvCostBreakdown_RowCommand" ... 

Step 2: Add CommandName property in your LinkButton inside your GridView:

<asp:LinkButton ID="btnAddRow" CommandName="AddRow" ...

Step 3: Remove UpdateMode="Conditional" ChildrenAsTriggers="true" in your first UpdatePanel (upSectionB) give ControlID as gvCostBreakdown and EventName as RowCommand of <Triggers>:

<Triggers>
    <asp:AsyncPostBackTrigger ControlID="gvCostBreakdown" EventName="RowCommand" />
</Triggers>

Step 4: Finally, in RowCommand event set the TextBox value from GridView row:

// Getting GridView row which clicked
GridViewRow row = (GridViewRow)((Control)e.CommandSource).NamingContainer;

// Check if LinkButton (AddRow) is clicked
if (e.CommandName=="AddRow")
{
    // getting the value of label inside GridView
    string rowCellValue = ((Label)row.FindControl("Label1")).Text;

    // setting value to TextBox which is inside First UpdatePanel
    txtTotal.Text = rowCellValue;
}

See full example below:

Code-Behind:

DataTable dt = new DataTable();

protected void Page_Load(object sender, EventArgs e)
{
    // adding dummy data into DataTable
    if (dt.Rows.Count == 0)
    {
        dt.Columns.Add("Column1");
        dt.Rows.Add("Row1");
        dt.Rows.Add("Row2");
    }

    if (!IsPostBack)
    {
        // setting and binding DataTable to GridView
        gvCostBreakdown.DataSource = dt;
        gvCostBreakdown.DataBind();
    }
}

protected void gvCostBreakdown_RowCommand(object sender, GridViewCommandEventArgs e)
{
    // Getting GridView row which clicked
    GridViewRow row = (GridViewRow)((Control)e.CommandSource).NamingContainer;

    // Check if LinkButton (AddRow) is clicked
    if (e.CommandName=="AddRow")
    {
        // getting the value of label inside GridView
        string rowCellValue = ((Label)row.FindControl("Label1")).Text;

        // setting value to TextBox which is inside First UpdatePanel
        txtTotal.Text = rowCellValue;
    }
}

.Aspx Code:

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>

<asp:UpdatePanel ID="upSectionB" runat="server">
    <ContentTemplate>
        TextBox:
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><br /><br />
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="gvCostBreakdown" EventName="RowCommand" />
    </Triggers>
</asp:UpdatePanel>

<asp:UpdatePanel ID="upSectionC" runat="server">
    <ContentTemplate>
        GridView: </b>
        <asp:GridView ID="gvCostBreakdown" runat="server" OnRowCommand="gvCostBreakdown_RowCommand" AutoGenerateColumns="false">
            <Columns>
                <asp:TemplateField HeaderText="Column1">
                    <ItemTemplate>
                        <asp:Label ID="Label1" runat="server" Text='<%# Eval("Column1") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Column2">
                    <ItemTemplate>
                        <asp:LinkButton ID="btnAddRow" CommandName="AddRow" runat="server">Add Row</asp:LinkButton>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
    </ContentTemplate>
</asp:UpdatePanel>

.GIF Image Demo:

enter image description here

like image 31
stefan Avatar answered Nov 15 '22 13:11

stefan