Question

Visual Studio 2010, .NET Framework 4.0 Trying to manually add an AjaxControlToolkit CascadingDropDown extender to a webpage dynamically. The web page has a placeholder. When it posts back the controls are built dynamically and added to the placeholder. I have regular ASP.NET drop down list boxes that I want to add CascadingDropDown extender to.

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)

The error is the last line where it is adding the CascadingDropDown. The error is:

Value cannot be null. Parameter name: No target control is set for the CascadingDropDown extender.

And if you look at the property TargetControl on myCascadingDropDown it is null (nothing). But you can not set it (it is read only). I assumed that since I set TargetControlID that ASP.NET would set TargetControl from the TargetControlID.

Any ideas or suggestions?

More complete exception:
System.ArgumentNullException was unhandled by user code Message=Value cannot be null.
Parameter name: No target control is set for the CascadingDropDown extender. ParamName=No target control is set for the CascadingDropDown extender.
Source=AjaxControlToolkit
StackTrace:
at AjaxControlToolkit.CascadingDropDown.CascadingDropDown_ClientStateValuesLoaded(Object sender, EventArgs e)
at AjaxControlToolkit.ExtenderControlBase.LoadClientStateValues()
at AjaxControlToolkit.ExtenderControlBase.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.AddedControl(Control control, Int32 index)
at System.Web.UI.ControlCollection.Add(Control child)

ANSWER in VB.NET:

Yuriy Rozhovetskiy nailed it. I am programming this application in vb.net so first I created a global variable (my functions in this class are shared/static):

Shared ControlToResolve As System.Web.UI.Control  

Then the code I created was:

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)  

then the handler is:

Shared Sub myCascadingDropDown_ResolveControlID(sender As Object, e As ResolveControlEventArgs)
    e.Control = ControlToResolve
End Sub  

I defined the TargetControl of the CascadingDropDown as "ControlToResolve". I set ControlToResolve to the target Drop Down List Box before I add the CascadingDropDown to the panel holding the controls. When I add the CascadingDropDown, it calls the handler myCascadingDropDown_ResolveControlID which assigns the drop down list box to the CascadingDropDown.Target

My web service looks like:

<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  

and it calls this web service with my ControlID every time I need values in one of the drop down list boxes. BTW - using the ControlID I can tell which drop down list box wants data, if it is a parent or child drop down list box and can go get the data.

Was it helpful?

Solution

There are two available solutions: first one is to place target control and extender in same naming container and the second is to subscribe on extender's ResolveControlID event and in this event handler set target control directly to eventArgs.Control property. C# code below:

myCascadingDropDown.ResolveControlID += myCascadingDropDown_ResolveControlID;

void myCascadingDropDown_ResolveControlID(object sender, ResolveControlEventArgs e)
{
    e.Control = myDisplayedField;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top