手动添加ajax控件工具包级联下拉列表

时间:2013-04-16 16:08:57

标签: ajaxcontroltoolkit cascadingdropdown

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我可以告诉哪个下拉列表框想要数据,如果它是父或子下拉列表框并且可以获取数据。

1 个答案:

答案 0 :(得分:0)

有两种可用的解决方案:第一种是将目标控件和扩展器放在同一个命名容器中,第二种是订阅扩展器的ResolveControlID事件,并在此事件中将目标控件直接设置为eventArgs.Control属性。 C#代码如下:

myCascadingDropDown.ResolveControlID += myCascadingDropDown_ResolveControlID;

void myCascadingDropDown_ResolveControlID(object sender, ResolveControlEventArgs e)
{
    e.Control = myDisplayedField;
}