我有一个FormView,我需要访问其中的一些Div和其他控件。我的apsx代码与此类似:
<asp:FormView ID="Edit_FV" runat="server" DataKeyNames="IDproceso" DefaultMode="Edit" DataSourceID="SqlDS_Procesos">
<EditItemTemplate>
<div id="second_info" runat="server">
<div id="second_info_left" runat="server">
<div id="alcance" class="report_field" runat="server">
<p class="container-title">
Alcance:</p>
<asp:TextBox ID="TextBox14" runat="server" TextMode="multiline" Width="400px" Height="120px" Text='<%# Bind("alcance") %>' />
</div>
</div>
<div id="second_info_right" runat="server">
<div class="valores-container" id="tipo_ahorro" runat="server">
<asp:CheckBox ID="ahorro_state" runat="server" Checked='<%# Bind("tipo_ahorro") %>' />
</div>
</div>
</EditItemTemplate>
</asp:FormView>
现在,假设我要使用CheckBox
访问id = ahorro_state
,我尝试使用Edit_FV.FindControl("ahorro_state")
并获得了空引用。我也试过Edit_FV.FindControl("MainContent_Edit_FV_ahorro_state")
,因为这是ID在最终的HTML文档中实际命名的方式,但我也得到了一个Null引用。当我尝试访问任何div(ID为second_info
,tipo_ahorro
等)时,也发生了同样的情况。我觉得自己犯了一个愚蠢的错误,但我环顾四周,找不到答案。
任何想法如何解决这个问题?
编辑:在我调用FindControl时添加了代码。
我尝试从Page_Load()中调用DataBind():
protected void Page_Load(object sender, EventArgs e)
{
DataBind();
if (Edit_FV.CurrentMode == FormViewMode.Edit)
{
Control c = Edit_FV.FindControl("ahorro_state");//c is null here.
}
}
还尝试设置Edit_FV的OnDataBound属性:OnDataBound="onBound"
protected void onBound(object sender, EventArgs e)
{
if (Edit_FV.CurrentMode == FormViewMode.Edit)
{
ControlCollection a = Edit_FV.Controls;
Control c = Edit_FV.FindControl("ahorro_state");//c is null here
}
}
答案 0 :(得分:1)
虽然默认模式设置为“编辑”,但在控件为DataBound之前,表单视图不会切换到该模式。首先尝试调用DataBind()
,然后使用元素的ID使用FindControl(而不是您在第二个示例中尝试的ClientID)。
有关FindControl逻辑放置位置的示例,请参阅FormView.FindControl(): object reference error。
编辑:
您的数据源也可能没有返回任何数据。这将导致EditItemTemplate为空,这可能会解释您的空引用错误。在切换到编辑模式之前,请尝试检查Edit_FV.DataItemCount > 0
。
答案 1 :(得分:1)
我遇到过类似'FindControl'的问题。我发现了一段帮助我的代码.a)递归地查找控件,以及b)调试语句非常有助于了解为什么我找不到有问题的控件。
为了帮助我找到控件,我必须在找到它们时给它们ID值,如果它们没有默认值:
public static class General_ControlExtensions
{
//From: http://www.devtoolshed.com/content/find-control-templatefield-programmatically
/// <summary>
/// recursively finds a child control of the specified parent.
/// USAGE:
/// Control controlToFind = DetailsView1.fn_ReturnControl_givenControlID("txtName");
/// </summary>
/// <param name="rootControl"></param>
/// <param name="ID"></param>
/// <returns></returns>
public static Control fn_ReturnControl_givenControlID(this Control rootControl, string ID)
{
if (rootControl.ID == ID)
{
return rootControl;
}
foreach (Control control in rootControl.Controls)
{
Debug.WriteLine("FindByID - child.id: " + control.ID);
Control foundControl = fn_ReturnControl_givenControlID(control, ID);
if (foundControl != null)
{
return foundControl;
}
}
return null;
}
以下是其用法示例:
using System.Diagnostics; // for debug
TextBox txt_LastName = (TextBox)fv_NewHire_DetailsForm.fn_ReturnControl_givenControlID("INSERT_txt_LastName");
此外,我发现在'insertitemtemplate'中使用'INSERT_'开头的控件以及'edititemtemplate'中带有'EDIT_'的控件在调试输出中快速区分它们对此类问题很有帮助