Visual Studio 2010,.NET Framework 4.0 尝试动态地将AjaxControlToolkit CascadingDropDown扩展器手动添加到网页。 该网页有一个占位符。当它回发时,控件是动态构建的并添加到占位符中。我有常规的ASP.NET下拉列表框,我想将CascadingDropDown扩展器添加到。
myCascadingDropDown = New AjaxControlToolkit.CascadingDropDown
myCascadingDropDown.ID = "cdd_" & myDisplayedField.ControlID
myCascadingDropDown.BehaviorID = "cdd_" & myDisplayedField.ControlID
myCascadingDropDown.TargetControlID = myDisplayedField.ControlID
myCascadingDropDown.Category = myDisplayedField.ControlID
myCascadingDropDown.PromptText = "Select " & aField.Caption
myCascadingDropDown.ServicePath = "CascadingDropDown.asmx"
myCascadingDropDown.ServiceMethod = "DropDownListBoxChanged"
myPanelForFields.Controls.Add(myCascadingDropDown)
错误是添加CascadingDropDown的最后一行。错误是:
值不能为空。参数
name
:没有为CascadingDropDown
扩展器设置目标控件。
如果你在myCascadingDropDown上查看属性TargetControl,它就是null(没有)。但你不能设置它(它是只读的)。我假设因为我设置了TargetControlID,ASP.NET会从TargetControlID设置TargetControl。
有任何想法或建议吗?
更完整的例外:
System.ArgumentNullException未被用户代码处理
消息=值不能为空。
参数名称:没有为CascadingDropDown扩展器设置目标控件。
ParamName =没有为CascadingDropDown扩展器设置目标控制
来源= AjaxControlToolkit
堆栈跟踪:
在AjaxControlToolkit.CascadingDropDown.CascadingDropDown_ClientStateValuesLoaded(Object sender,EventArgs e)
在AjaxControlToolkit.ExtenderControlBase.LoadClientStateValues()
在AjaxControlToolkit.ExtenderControlBase.OnLoad(EventArgs e)
在System.Web.UI.Control.LoadRecursive()
在System.Web.UI.Control.AddedControl(控制控件,Int32索引)
在System.Web.UI.ControlCollection.Add(控制子)
VB.NET中的答案:
Yuriy Rozhovetskiy钉了它。我在vb.net中编写这个应用程序,所以首先我创建了一个全局变量(我在这个类中的函数是共享/静态的):
Shared ControlToResolve As System.Web.UI.Control
然后我创建的代码是:
myCascadingDropDown = New AjaxControlToolkit.CascadingDropDown
myCascadingDropDown.ID = "cdd_" & myDisplayedField.ControlID
myCascadingDropDown.BehaviorID = "cdd_" & myDisplayedField.ControlID
myCascadingDropDown.TargetControlID = myDisplayedField.ControlID
myCascadingDropDown.Category = myDisplayedField.ControlID
myCascadingDropDown.PromptText = "Select " & aField.Caption
myCascadingDropDown.ServicePath = "CascadingDropDown.asmx"
myCascadingDropDown.ServiceMethod = "DropDownListBoxChanged"
ControlToResolve = myBSCComboBox
AddHandler myCascadingDropDown.ResolveControlID, AddressOf myCascadingDropDown_ResolveControlID
myPanelForFields.Controls.Add(myCascadingDropDown)
然后处理程序是:
Shared Sub myCascadingDropDown_ResolveControlID(sender As Object, e As ResolveControlEventArgs)
e.Control = ControlToResolve
End Sub
我将CascadingDropDown的TargetControl定义为“ControlToResolve”。在将CascadingDropDown添加到包含控件的面板之前,我将ControlToResolve设置为目标下拉列表框。当我添加CascadingDropDown时,它调用处理程序myCascadingDropDown_ResolveControlID,它将下拉列表框分配给CascadingDropDown.Target
我的网络服务如下:
<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<System.Web.Script.Services.ScriptService()> _
<ToolboxItem(False)> _
Public Class CascadingDropDown
Inherits System.Web.Services.WebService
<WebMethod(EnableSession:=True)> _
Public Function DropDownListBoxChanged(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
End Function
每当我需要其中一个下拉列表框中的值时,它就会使用我的ControlID调用此Web服务。 BTW - 使用ControlID我可以告诉哪个下拉列表框想要数据,如果它是父或子下拉列表框并且可以获取数据。
答案 0 :(得分:0)
有两种可用的解决方案:第一种是将目标控件和扩展器放在同一个命名容器中,第二种是订阅扩展器的ResolveControlID
事件,并在此事件中将目标控件直接设置为eventArgs.Control属性。 C#代码如下:
myCascadingDropDown.ResolveControlID += myCascadingDropDown_ResolveControlID;
void myCascadingDropDown_ResolveControlID(object sender, ResolveControlEventArgs e)
{
e.Control = myDisplayedField;
}