3

我有一个正在构建的用户控件(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,会抛出.drpShipTohdnAvailableProductId FindControlNullReferenceException

我并不是说它返回“null”,我尝试访问返回对象的属性,该方法FindControl抛出异常。根据 MSDN 库,这是不可能的 -FindControl没有将任何内容列为潜在的抛出错误,它只是说如果找不到控件,则返回 null。

什么会导致FindControlNullReferenceException?

- - - - - - - - -编辑 - - - - - - - -

我还应该提到,如果我在即时窗口中运行三个有问题的行中的任何一行,我都会得到正确的结果。当我在调试时检查它时,ControlCollection我还可以看到其中的控件。pnlForm

-----------------第二次编辑-----------------

为了确认,我添加了另一行: DropDownList notThere = (DropDownList)pnlForm.FindControl("notHere"); 该控件notHere不在页面上的任何位置。上面的行编译(当然),当我运行调试器时,它运行良好。演员阵容很好。该变量notThere只是为空。

此问题的根本原因是 NOT FindControl 未能找到控件并尝试将 null 强制转换为 DropDownList 或其他控件

4

3 回答 3

9

导致问题的不是 FindControl。

您对其进行编码的方式是在一行上执行两个操作 - FindControl(),然后强制转换为控制数据类型。轰炸的是演员阵容,因为 FindControl 调用的结果是 null 值,而您正试图将 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.
}
于 2011-01-28T14:48:40.983 回答
7

转换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(-implementation) 与用户控件上的控件进行通信。

恕我直言findcontrol,这是一项在全球范围内被滥用的功能......(小猫因使用它而被杀)

于 2011-01-28T14:49:56.163 回答
0

你得到一个 NullReferenceException,它没有找到(你正在寻找的)控件

尝试:

DropDownList drpLanguage = (DropDownList)(pnlForm.FindControl("drpLanguage"));
DropDownList drpShipTo = (DropDownList)(pnlForm.FindControl("drpShipTo"));
HiddenField hdnAvailableProductId = (HiddenField)(pnlForm.FindControl("hdnAvailableProductId"));
于 2011-01-28T14:48:17.737 回答