我正在构建一个用户控件(ASP.NET 3.5,使用C#)。
这个控件很大程度上基于另一个类似的控件(不幸的是,剪切和粘贴继承,但是没有简单的方法来抽象它)。给我带来麻烦的行直接从其他控件复制,就像显示器的大部分一样。
相关的代码行如下:
Panel pnlForm = (Panel)e.Item.FindControl("pnlForm");
Literal ltrAvailableCount = (Literal)e.Item.FindControl("ltrAvailableCount");
DropDownList drpLanguage = (DropDownList)pnlForm.FindControl("drpLanguage");
DropDownList drpShipTo = (DropDownList)pnlForm.FindControl("drpShipTo");
HiddenField hdnAvailableProductId = (HiddenField)pnlForm.FindControl("hdnAvailableProductId");
DropDownList drpQuantity = (DropDownList)pnlForm.FindControl("drpQuantity");
HiddenField hdnSelectedStyle = (HiddenField)e.Item.FindControl("hdnSelectedStyle");
Label lblStyleName = (Label)e.Item.FindControl("lblSelectedStyle");
上面的 pnlForm
被正确找到,ltrAvailableCount
也是如此。
如果我跳到drpQuantity
,它和以下行可以正常工作。但是,当我运行drpLanguage
,drpShipTo
或hdnAvailableProductId
FindControl
的行时会抛出NullReferenceException
。
我不是说它返回'null'并且我尝试访问返回对象的属性,方法FindControl
抛出异常。根据MSDN库,这是不可能的 - FindControl
不会将任何内容列为潜在的抛出错误,它只是说如果它找不到Control,它将返回null。
什么可能导致FindControl
NullReferenceException?
-----------------编辑---------------
我还应该提一下,如果我在即时窗口中运行三个有问题的行中的任何一行,我会得到正确的结果。我还可以在调试时检查ControlCollection
pnlForm
中的控件。
-----------------第二编辑-------------------
为了确认,我添加了另一条线:
DropDownList notThere =(DropDownList)pnlForm.FindControl(“notHere”);
控件notHere
不在页面的任何位置。上面的行编译(当然),当我运行调试器时,它运行正常。演员阵容很好。变量notThere
只是空。
此问题的根本原因是FindControl无法找到控件并尝试将null转换为DropDownList或其他控件
答案 0 :(得分:8)
导致问题的不是FindControl。
你编写它的方式是在一行上执行两个操作 - FindControl()然后转换为控件数据类型。这是轰炸的演员阵容,因为FindControl调用的结果是空值,并且您正在尝试将null转换为控件。
这一点我很多次,所以我学会了把它编码为
object oDropDown1 = pnlForm.FindControl("DropDown1");
// then check if oDrowpDown 1 is null and cast if it's safe.
if(oDropDown1 != null)
{
// here it's safe to cast.
}
答案 1 :(得分:5)
将null
转换为DropDownList将导致异常。
如果pnlForm.FindControl("drpQuantity")
返回null
,则无法投射;)
然而这将起作用:
System.Web.UI.WebControls.DropDownList drpQuantity =
pnlForm.FindControl("drpQuantity") as System.Web.UI.WebControlsDropDownList;
if(drpQuantity!=null){
//use drpQuantity here
}
as运算符用于执行兼容类型之间的转换.as运算符类似于转换,除了它在转换失败时产生null而不是引发异常。
无论如何,findcontrol
的使用仅适用于数据生成的控件,在所有其他情况下使用interface
( - 实现)与用户控件的控件进行通信。
恕我直言findcontrol
是一个全球滥用的功能....(小猫因使用它而被杀死)
答案 2 :(得分:0)
你得到一个NullReferenceException,它没有找到(你正在寻找的)控件
尝试:
DropDownList drpLanguage = (DropDownList)(pnlForm.FindControl("drpLanguage"));
DropDownList drpShipTo = (DropDownList)(pnlForm.FindControl("drpShipTo"));
HiddenField hdnAvailableProductId = (HiddenField)(pnlForm.FindControl("hdnAvailableProductId"));