Reputation: 491
I am trying to find a server control inside gridiview template field on row data bound but it returns null. Why ?
I am trying to find a
control which has runat attribute but it returns null.
Actually i am trying to load HTML text in this control.
protected void gvBidDetails_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var paraAgreement = e.Row.FindControl("paraAgreement") as Literal;
paraAgreement.Text = "sahdbaskjdbasjbdjabsdbhasdbhasjbhdab<br/>sdbasdbhasdjabjdbasjdbjasbhdashhhdbasdbhab<br/>shdbhashbdashbdashdabshdbhasdbjabsdabsdbhasbhdashdbasd";
}
}
catch (Exception ex)
{
Utility.Msg_Error(Master, ex.Message);
}
}
.aspx
<asp:TemplateField HeaderText='Finalized ?'>
<ItemTemplate>
<asp:LinkButton ID="btnFinalizedRecord" OnClick="btnFinalizedRecord_Click" runat="server" Text='<%# Convert.ToBoolean(Eval("IsFinalized")) == true? "": "Finalize" %>'
CssClass="" ToolTip="Finalize" CommandName="Finalize"
CommandArgument='<%#Eval("IsFinalized")%>' Enabled='<%# Convert.ToBoolean(Eval("IsFinalized")) == true? false: true %>'></asp:LinkButton>
<ajax:confirmbuttonextender id="ConfirmButtonExtender1" runat="server" displaymodalpopupid="mpe2" targetcontrolid="btnFinalizedRecord">
</ajax:confirmbuttonextender>
<ajax:modalpopupextender id="mpe2" runat="server" popupcontrolid="pnlPopup2" targetcontrolid="btnFinalizedRecord" okcontrolid="btnYes"
cancelcontrolid="btnNo" backgroundcssclass="modalBackground">
</ajax:modalpopupextender>
<asp:Panel ID="pnlPopup2" runat="server" CssClass="modalPopup" Style="display: none">
<div class="header">
Are you sure to <b>Finalize</b>?
</div>
<div class="body">
<asp:CheckBox ID="chkConfirmFinalize" runat="server" />
<%--<a href="TermsAndConditions.aspx" target="_blank">Agree with the Terms and Conditions</a>--%>
<p runat="server" id="paraAgreement">
</p>
</div>
<div class="Popupfooter" align="right">
<asp:Button ID="btnYes" Enabled="false" CssClass="btn btn-sm btn-danger btnYes" runat="server" Text="Yes" />
<asp:Button ID="btnNo" CssClass="btn btn-sm btn-primary" runat="server" Text="No" />
</div>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
Upvotes: 0
Views: 1364
Reputation: 24957
Edit 1:
You're trying to cast FindControl
result into Literal
and it returns null due to the HTML paragraph server control recognized as System.Web.UI.HtmlControls.HtmlGenericControl
and as
keyword silently swallowed InvalidCastException
below:
Unable to cast object of type 'System.Web.UI.HtmlControls.HtmlGenericControl' to type 'System.Web.UI.WebControls.Literal'.
Hence, the FindControl
assignment should be like this example:
protected void gvBidDetails_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var paraAgreement = e.Row.FindControl("paraAgreement") as HtmlGenericControl;
paraAgreement.InnerText = "[sample text]";
}
}
catch (Exception ex)
{
Utility.Msg_Error(Master, ex.Message);
}
}
Another way to find nested child controls by control ID is by doing recursive search throughout parent control using customized method (credits to @Win):
// taken from /a/15708885/6378815
public static Control FindControlRecursive(Control parentControl, string id)
{
if (parentControl.ID == id)
{
return parentControl;
}
return parentControl.Controls.Cast<Control>().Select(c => FindControlRecursive(c, id)).FirstOrDefault(c => c != null);
}
// GridView event method
protected void gvBindDetails_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var paraAgreement = new HtmlGenericControl();
foreach (Control control in gvBindDetails.Rows)
{
paraAgreement = FindControlRecursive(control, "paraAgreement") as HtmlGenericControl;
}
paraAgreement.InnerText = "[sample text]";
}
}
catch (Exception ex)
{
Utility.Msg_Error(Master, ex.Message);
}
}
Additional reference:
System.Web.UI.HtmlControls.HtmlGenericControl (MSDN)
Related issues:
Find Controls nested inside Repeater Control
Better way to find control in ASP.NET
Upvotes: 2
Reputation: 35514
You are using FindControl
to search for a Literal
. But paraAgreement
is not an actual asp:Literal
Control. So it always return null
.
Use HtmlGenericControl
instead.
HtmlGenericControl p = e.Row.FindControl("paraAgreement") as HtmlGenericControl;
p.InnerHtml = "Found the Control";
Upvotes: 1