locked
Render method not applying for gridview in update panel on a user control RRS feed

  • Question

  • User-1547019860 posted
    I have a user control with a grid view that I wish the user to be able to click the row and cause the selectedIndexChanged event to fire on the grid view. To do this I have overridden the Render method on the user control to do the following:

    protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
       if (GridView1.Rows.Count > 0)
       {
          foreach (GridViewRow row in GridView1.Rows)
          {
             if (row.RowType == DataControlRowType.DataRow)
             {
                row.Attributes[
    "onclick"] = Page.ClientScript.GetPostBackEventReference(this.GridView1, "Select$" + row.RowIndex, true);
                row.Style[
    "cursor"] = "hand";
             }
          }
       }
    base.Render(writer);
    }

    However, If I put a update panel around my grid, this no longer works (the style and onclick attribute are no longer available). The exact same code placed directly on a page will work correctly. I have spent hours looking into this and as I cannot find anything, I can only assume that I am missing something fundamental. I can post a full example if it will help. Cheers

     

    Thursday, January 22, 2009 5:46 AM

Answers

  • User1335925338 posted

    Hi seanoc,

    I have built a test application based on your description and your code,  but it can work well locally.

    Here is my code:

    .ascx file 

    <%@ Control Language="vb" AutoEventWireup="false" CodeBehind="RenderUC.ascx.vb" Inherits="SoluTest_GetValueFromUserControl.RenderUC" %>
    <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1"
        Width="253px">
        <Columns>
            <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" SortExpression="ID" />
            <asp:BoundField DataField="Field1" HeaderText="Name" SortExpression="Field1" />
            <asp:BoundField DataField="Field2" HeaderText="Value" SortExpression="Field2" />
        </Columns>
    </asp:GridView>
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:DatabaseConnectionString %>"
        ProviderName="<%$ ConnectionStrings:DatabaseConnectionString.ProviderName %>"
        SelectCommand="SELECT AssName.ID, AssName.Field1, Detail.Field2 FROM (AssName INNER JOIN Detail ON AssName.Field1 = Detail.Field1)">
    </asp:SqlDataSource>
    .ascx.vb file 
    Public Partial Class RenderUC
        Inherits System.Web.UI.UserControl
    
        Protected Overloads Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
            If GridView1.Rows.Count &gt; 0 Then
                For Each row As GridViewRow In GridView1.Rows
                    If row.RowType = DataControlRowType.DataRow Then
                        row.Attributes("onclick") = Page.ClientScript.GetPostBackEventReference(Me.GridView1, "Select$" + row.RowIndex.ToString, True)
                        row.Style("cursor") = "hand"
                    End If
                Next
            End If
            MyBase.Render(writer)
        End Sub
    
        Private Sub GridView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView1.SelectedIndexChanged
            Label1.Text = "You have selected row" + GridView1.SelectedIndex.ToString
        End Sub
    
    End Class
    .aspx file 
    <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="TestRenderUC.aspx.vb"
        Inherits="SoluTest_GetValueFromUserControl.TestRenderUC" %>
    
    <%@ Register src="RenderUC.ascx" TagName="RenderUC" TagPrefix="uc1" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:ScriptManager ID="ScriptManager1" runat="server" />
            <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>
                    <uc1:RenderUC ID="RenderUC1" runat="server" />
                </ContentTemplate>
            </asp:UpdatePanel>
        </div>
        </form>
    </body>
    </html>
    If I have misunderstood you, please post you related code.

    Best regards,

    Zhi-Qiang Ni

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, January 28, 2009 1:44 AM

All replies

  • User1335925338 posted

    Hi seanoc,

    I have built a test application based on your description and your code,  but it can work well locally.

    Here is my code:

    .ascx file 

    <%@ Control Language="vb" AutoEventWireup="false" CodeBehind="RenderUC.ascx.vb" Inherits="SoluTest_GetValueFromUserControl.RenderUC" %>
    <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1"
        Width="253px">
        <Columns>
            <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" SortExpression="ID" />
            <asp:BoundField DataField="Field1" HeaderText="Name" SortExpression="Field1" />
            <asp:BoundField DataField="Field2" HeaderText="Value" SortExpression="Field2" />
        </Columns>
    </asp:GridView>
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:DatabaseConnectionString %>"
        ProviderName="<%$ ConnectionStrings:DatabaseConnectionString.ProviderName %>"
        SelectCommand="SELECT AssName.ID, AssName.Field1, Detail.Field2 FROM (AssName INNER JOIN Detail ON AssName.Field1 = Detail.Field1)">
    </asp:SqlDataSource>
    .ascx.vb file 
    Public Partial Class RenderUC
        Inherits System.Web.UI.UserControl
    
        Protected Overloads Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
            If GridView1.Rows.Count &gt; 0 Then
                For Each row As GridViewRow In GridView1.Rows
                    If row.RowType = DataControlRowType.DataRow Then
                        row.Attributes("onclick") = Page.ClientScript.GetPostBackEventReference(Me.GridView1, "Select$" + row.RowIndex.ToString, True)
                        row.Style("cursor") = "hand"
                    End If
                Next
            End If
            MyBase.Render(writer)
        End Sub
    
        Private Sub GridView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView1.SelectedIndexChanged
            Label1.Text = "You have selected row" + GridView1.SelectedIndex.ToString
        End Sub
    
    End Class
    .aspx file 
    <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="TestRenderUC.aspx.vb"
        Inherits="SoluTest_GetValueFromUserControl.TestRenderUC" %>
    
    <%@ Register src="RenderUC.ascx" TagName="RenderUC" TagPrefix="uc1" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:ScriptManager ID="ScriptManager1" runat="server" />
            <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>
                    <uc1:RenderUC ID="RenderUC1" runat="server" />
                </ContentTemplate>
            </asp:UpdatePanel>
        </div>
        </form>
    </body>
    </html>
    If I have misunderstood you, please post you related code.

    Best regards,

    Zhi-Qiang Ni

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, January 28, 2009 1:44 AM
  • User-1547019860 posted

    Hi Zhi-Qiang Ni,

    Firstly, thank you for your reply and taking the time to look at the issue I am having. The code that you have tried will work, however in my issue, the update panel is in the ascx control, not wrapped around it on the hosting page.

    I think that if you try the following, you may find it will not work and this is my problem. I do not want the whole user control in an update panel, just a portion of the user control's content.

    .ascx file 

    <%@ Control Language="vb" AutoEventWireup="false" CodeBehind="RenderUC.ascx.vb" Inherits="SoluTest_GetValueFromUserControl.RenderUC" %>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
    <asp:Label ID="Label1" runat="server" Text=""></asp:Label> <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" Width="253px"> <Columns> <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" SortExpression="ID" /> <asp:BoundField DataField="Field1" HeaderText="Name" SortExpression="Field1" /> <asp:BoundField DataField="Field2" HeaderText="Value" SortExpression="Field2" /> </Columns> </asp:GridView>

     

    </ContentTemplate>

     

    </asp:UpdatePanel>

    <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:DatabaseConnectionString %>" ProviderName="<%$ ConnectionStrings:DatabaseConnectionString.ProviderName %>" SelectCommand="SELECT AssName.ID, AssName.Field1, Detail.Field2 FROM (AssName INNER JOIN Detail ON AssName.Field1 = Detail.Field1)"> </asp:SqlDataSource>

    Best Regards,

    Seanoc

    Wednesday, January 28, 2009 4:12 AM
  • User1335925338 posted

    Hi seanoc,

    Please write the “if” block  in the UserControl’s load event handler—Page_Load() method.

    Best regards,

    Zhi-Qiang Ni

    Wednesday, January 28, 2009 4:47 AM
  • User-1547019860 posted

    Hi ,

    When you say, "if" block, are you refering to the code in the render method. I cannot place the "Page.ClientScript.GetPostBackEventReference" code anywhere but in the Render method without having to turn off page validation for the entire page. Otherwise I would put it in the GridView1_RowDataBound event. Putting it in the load event causes a error. 

    Thanks,

    Seanoc

    Wednesday, January 28, 2009 4:59 AM
  • User1335925338 posted

    Hi seanoc,

    Sorry for my neglect of the EventValidation, please refer to this code: 

    Public Partial Class RenderUC
        Inherits System.Web.UI.UserControl
    
        Protected Overloads Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
            If GridView1.Rows.Count &gt; 0 Then
                For Each row As GridViewRow In GridView1.Rows
                    If row.RowType = DataControlRowType.DataRow Then
                        Page.ClientScript.RegisterForEventValidation(Me.GridView1.UniqueID, "Select$" + row.RowIndex.ToString)
                    End If
                Next
            End If
    
            MyBase.Render(writer)
        End Sub
    
        Private Sub GridView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView1.SelectedIndexChanged
            Label1.Text = "You have selected row" + GridView1.SelectedIndex.ToString
        End Sub
    
        Private Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If GridView1.Rows.Count > 0 Then
                For Each row As GridViewRow In GridView1.Rows
                    If row.RowType = DataControlRowType.DataRow Then
                        'row.Attributes("onclick") = Page.ClientScript.GetPostBackEventReference(Me.GridView1, "Select$" + row.RowIndex.ToString, True)
                        row.Attributes("onclick") = "__doPostBack('" + Me.GridView1.UniqueID + "','Select$" + row.RowIndex.ToString + "')"
                        row.Style("cursor") = "hand"
                    End If
                Next
            End If
        End Sub
    End Class
    Best regards,

    Zhi-Qiang Ni

    Wednesday, January 28, 2009 5:17 AM
  • User2060744668 posted

    Actualy none of the examples above works. I've spent 2 days on this issue but in the end I figgured out how to solve it. 

    This is how you solve it without Event Validation :

    Create a TestPage.aspx Page and WebUserTest.ascx User control.

    TestPage contains this:

    <form id="form1" runat="server">
      <uc1:WebUserTest ID="WebUserTest1" runat="server" />
    </form>

    WebUserTest user control contains this:

            <asp:ScriptManager runat="server">
            </asp:ScriptManager>
            <asp:UpdatePanel runat="server" id="upanel">
                <ContentTemplate>
                    <asp:GridView ID="GridView1" runat="server" AllowPaging="True" 
                        AutoGenerateColumns="False" CellPadding="4" DataSourceID="ObjectDataSource1" 
                        ForeColor="#333333" GridLines="None" Width="260px">
                        <AlternatingRowStyle BackColor="White" />
                        <Columns >
                            <asp:TemplateField ShowHeader="False">
                                <ItemTemplate>
                                    <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False" 
                                        CommandName="Select" Text="Select"></asp:LinkButton>
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="id" SortExpression="id">
                                <ItemTemplate>
                                    <asp:Label ID="Label1" runat="server" Text='<%# Bind("id") %>' ></asp:Label>
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name">
                            </asp:BoundField>
                        </Columns>
                        <EditRowStyle BackColor="#2461BF" />
                        <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
                        <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
                        <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
                        <RowStyle BackColor="#EFF3FB" />
                        <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
                        <sortedascendingcellstyle backcolor="#F5F7FB" />
                        <sortedascendingheaderstyle backcolor="#6D95E1" />
                        <sorteddescendingcellstyle backcolor="#E9EBEF" />
                        <sorteddescendingheaderstyle backcolor="#4870BE" />
                        <sortedascendingcellstyle backcolor="#F5F7FB" />
                        <sortedascendingheaderstyle backcolor="#6D95E1" />
                        <sorteddescendingcellstyle backcolor="#E9EBEF" />
                        <sorteddescendingheaderstyle backcolor="#4870BE" />
                    </asp:GridView>
                </ContentTemplate>
    
            </asp:UpdatePanel>
    
                    <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" EnablePaging="True" 
                        OldValuesParameterFormatString="original_{0}" SelectCountMethod="Count" 
                        SelectMethod="GetAll" TypeName="AjaxSamples.GridObjects">
                    </asp:ObjectDataSource>

    In the code behind of the user control:

            protected void Page_Load(object sender, EventArgs e)
            {
                this.GridView1.RowDataBound += new GridViewRowEventHandler(GridView1_RowDataBound);
            }
    
            void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
            {
                if (e.Row.RowType == DataControlRowType.DataRow)
                {
                    LinkButton LinkButton = e.Row.FindControl("LinkButton1") as LinkButton;
                    e.Row.Attributes["onmouseover"] = "this.style.cursor='hand';this.style.background='#eeff00';";
                    e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';this.style.background='#ffffff';";
                    e.Row.Attributes["onclick"] = "__doPostBack('" + LinkButton.UniqueID + "','')";
                }
            }
    

    Sunday, December 8, 2013 1:52 PM