Search code examples
c#gridviewevalhtmlcontrols

Change button text in GridView - (GridView ItemTemplate buttons rendered as DataBoundLiteralControl)


I have 2 buttons in a column of my GridView control.

<asp:TemplateField ItemStyle-CssClass="minPadding">
    <ItemTemplate>
        <input  id="btnDateRange" type="button" value="Date Range" class="JQDatePicker SmallText FloatRight WrapButtonText" onclick="javascript:document.getElementById('hdnImpressionTagID').value = '<%# Eval("ImpressionTagID") %>'"/>
        <asp:Button ID="btnShowImpressions" CommandArgument='<%# Eval("ImpressionTagID") %>' CommandName="ShowImpressions" Text="Total Impressions" runat="server" UseSubmitBehavior="false" CssClass="SmallText FloatLeft WrapButtonText" Width="80px" />
    </ItemTemplate>
</asp:TemplateField>

The reason the first button is an HTML control is because when I try to use an asp:button - the onclick event doesn't work (note the #Eval statement inside the javascript call) Using a server control gives me the error : 'Server tag is not well formed'

I want to change the text of these buttons from my code behind. (I'm using c#)

I find the correct row index and I know they are in cell 5.

I can set the asp:Button control's text like so...

Button btn = ((Button)gridImpressionTags.Rows[i].Cells[5].FindControl("btnDateRange")); btn.Text = "This Text has changed!";

The problem is: The Web control btnDateRange appears as a DataBoundLiteralControl when referenced from code behind & I am unable to cast it as a button.

I am also unable to cast it as a literal. Unable to cast object of type 'System.Web.UI.DataBoundLiteralControl' to type 'System.Web.UI.WebControls.Literal'.

And casting it as a DataBoundLiteralControl works, but then doesn't allow me to change the text: System.Web.UI.DataBoundLiteralControl.Text' cannot be assigned to -- it is read only

Does anyone know why my HTML button is being rendered as a DataBoundLiteralControl ? Does anyone have any ideas for me to try for me at all ?

Any suggestions are appreciated!


Solution

  • Firstly - I couldn't have answered this without the help of codingBiz, so thanks dude !!

    The trick was to ditch the <input type="button"> type button and go for a server control, which adds the onclick event on the RowDataBound.

    The reason I couldn't go for this the first time round was because I needed to add some javascript to the onclick event, and while this would work on a standard HTML button control, it wouldn't work on the asp:button. CodingBiz pointed me towards adding the onclick event at RowDataBound. With a few code changes to be able to access the correct row and datakey data, I got it working...

    ASPX page :

    <asp:TemplateField>
        <ItemTemplate>
            <asp:Button runat="server" ID="btnDateRange" Text="asp Date Range" CssClass="JQDatePicker SmallText FloatRight WrapButtonText" />
            <asp:Button ID="btnShowImpressions" CommandArgument='<%# Eval("ImpressionTagID") %>' CommandName="ShowImpressions" Text="Total Impressions" runat="server" UseSubmitBehavior="false" CssClass="SmallText FloatLeft WrapButtonText" Width="80px" />
        </ItemTemplate>
    </asp:TemplateField>
    

    Code behind :

            protected void gridImpressionTags_OnRowDataBound(object sender, GridViewRowEventArgs e)
        {
            Button btnDateRange = e.Row.FindControl("btnDateRange") as Button;
    
             if (e.Row.RowType == DataControlRowType.DataRow)
            {
                Button btn = e.Row.Cells[5].Controls[1] as Button;
                string datakey = gridImpressionTags.DataKeys[e.Row.RowIndex].Value.ToString();
    
                 btn.Attributes["onclick"] = "javascript:document.getElementById('hdnImpressionTagID').value = '" + datakey + "'";
             }
        }