0

Visual Studio 2010, .NET Framework 4.0 尝试手动将 AjaxControlToolkit CascadingDropDown 扩展器动态添加到网页。该网页有一个占位符。当它回发时,控件会动态构建并添加到占位符中。我有想要添加 CascadingDropDown 扩展器的常规 ASP.NET 下拉列表框。

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 属性,它为空(无)。但是你不能设置它(它是只读的)。我假设因为我设置了 TargetControlID,所以 ASP.NET 会从 TargetControlID 设置 TargetControl。

有什么想法或建议吗?

更完整的异常:
System.ArgumentNullException 未被用户代码处理 Message=Value 不能为空。
参数名称:没有为 CascadingDropDown 扩展器设置目标控件。ParamName=没有为 CascadingDropDown 扩展器设置目标控件。
Source=AjaxControlToolkit
StackTrace:
在 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 服务。顺便说一句 - 使用 ControlID 我可以判断哪个下拉列表框需要数据,如果它是父或子下拉列表框并且可以获取数据。

4

1 回答 1

0

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

myCascadingDropDown.ResolveControlID += myCascadingDropDown_ResolveControlID;

void myCascadingDropDown_ResolveControlID(object sender, ResolveControlEventArgs e)
{
    e.Control = myDisplayedField;
}
于 2013-04-16T18:45:43.100 回答