Environment:
ASP.NET 3.5, VS2008 professional, C#, Windows7, IE8
RAD Control v 2010.1.309
I am creating an extended server control that inherits from the RadDateInput. The reason for this approach is that I want to be able to dynamically add asp.net validation controls based on a property that is set from the code behind of the containing page.
I have successfully accomplished this with an asp.net text box (and other asp.net controls). I override the CreateChildControls method. Next I dynamically create the needed validation controls. I set the ControlToValidate property of the asp.net validation control to the ID property of the Telerik control (as set in the asp.net page). So, if I'm generating a Required Feild validator, it might look like this
RequiredFieldValidator1.ControlToValidate = RadDateInput1.ID;
I get a runtime error "Unable to find control id 'RadDateInput1' referenced by the 'ControlToValidate' property of 'RequiredFieldValidator1'.
Note that this same approach does work with an ASP.NET text box. So my question is how can I determine what the ID of the RadDateInput is in my custom control?
Thanks!
7 Answers, 1 is accepted
Are you explicitly giving an ID to your RadDateInput? Can you post the custom control definition?
Regards,
Veli
the Telerik team

[
AspNetHostingPermission(SecurityAction.Demand,
Level = AspNetHostingPermissionLevel.Minimal),
AspNetHostingPermission(SecurityAction.InheritanceDemand,
Level = AspNetHostingPermissionLevel.Minimal),
DefaultEvent(
""
),
DefaultProperty(
""
),
ToolboxData(
"<{0}:Register runat=\"server\"> </{0}:Register>"
),
ValidationProperty(
"Text"
)
]
public
class
tlRadDateInput : RadDateInput, INamingContainer
//Have tried it with and without INamingContainer, no difference
{
[
Category(
"Misc"
),
Description(
"What you want this control to be refered to as if a validation message has to be displayed"
),
]
public
string
Name {
get
;
set
; }
//Note validatorCollection is not the framework collection, but a custom collection of IValidators
//which just represents the settings used to set an actual asp.net validator control
private
YourNameSpace.ValidatorCollection _ValidatorCollection;
[
Category(
"Behavior"
),
Description(
"The Business layer collection of validators that will be used to set the web validator parameters"
),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content),
//Editor(typeof(ContactCollectionEditor), typeof(UITypeEditor)),
PersistenceMode(PersistenceMode.Attribute)
]
public
YourNameSpace.ValidatorCollection validatorCollection
{
get
{
if
(_ValidatorCollection ==
null
)
return
new
YourNameSpace.ValidatorCollection();
return
_ValidatorCollection;
}
set
{
_ValidatorCollection = value;
}
}
private
ValidatorDisplay _validationDisplay;
[Bindable(
true
),
Category(
"Behavior"
),
DefaultValue(
""
),
Description(
"All validators will be assinged to this group."
)
]
public
ValidatorDisplay ValidatorDisplay
{
get
{
if
(_validationDisplay ==
null
)
return
ValidatorDisplay.Dynamic;
return
_validationDisplay;
}
set
{
_validationDisplay = value;
}
}
private
string
_webControlID;
public
String WebControlID
{
get
{
return
_webControlID; }
set
{ _webControlID = value; }
}
protected
override
void
CreateChildControls()
{
base
.CreateChildControls();
WebControlID =
this
.ID;
foreach
(YourNameSpace.IValidator validator
in
validatorCollection)
{
EnsureChildControls();
SetWebValidationControlProperties(validator);
}
}
protected
void
SetWebValidationControlProperties(YourNameSpace.IValidator blValidator)
{
//Set the asp.net validators to the settings from the business layer
//we case the IValidator to it's respective class, that just mimicks the asp.control of the same name
//you can simulate by just hard coding the vales
string
webValidatorName = blValidator.GetType().Name;
switch
(webValidatorName)
{
case
"RegularExpressionValidator"
:
var blRegEx = (YourNameSpace.RegularExpressionValidator)blValidator;
var RegularExpressionValidator1 =
new
RegularExpressionValidator();
RegularExpressionValidator1.ControlToValidate = WebControlID;
RegularExpressionValidator1.Enabled =
true
;
//RegularExpressionValidator1.ID = "RegularExpressionValidator1-" + WebControlID;
//"regx" + this.UniqueID;
RegularExpressionValidator1.Attributes[
"name"
] =
"regx-"
+ WebControlID;
RegularExpressionValidator1.Display =
this
.ValidatorDisplay;
RegularExpressionValidator1.ValidationExpression = blRegEx.GetValidationExpression();
RegularExpressionValidator1.ValidationGroup = ValidationGroup;
RegularExpressionValidator1.ErrorMessage = blRegEx.ErrorMessage;
RegularExpressionValidator1.Text = blRegEx.ErrorMessage;
Controls.Add(RegularExpressionValidator1);
break
;
case
"RangeValidator"
:
var blRangeVal = (YourNameSpace.RangeValidator)blValidator;
var RangeValidator1 =
new
RangeValidator();
RangeValidator1.ControlToValidate = WebControlID;
RangeValidator1.SetFocusOnError =
true
;
RangeValidator1.Attributes[
"name"
] =
"rng-"
+ WebControlID;
RangeValidator1.Display =
this
.ValidatorDisplay;
RangeValidator1.ValidationGroup = ValidationGroup;
RangeValidator1.Type = blRangeVal.validationDataType;
RangeValidator1.MinimumValue = blRangeVal.MinValue;
RangeValidator1.MaximumValue = blRangeVal.MaxValue;
//get the appropriate error message
//code to go get the error message, just hard code for example
string
RangeValErrorMessage =
"Range Error"
;
RangeValidator1.ErrorMessage = RangeValErrorMessage;
RangeValidator1.Text = RangeValErrorMessage;
Controls.Add(RangeValidator1);
break
;
case
"CompareValidator"
:
var blComppareVal = (YourNameSpace.CompareValidator)blValidator;
var CompareValidator1 =
new
CompareValidator();
CompareValidator1.ControlToValidate = WebControlID;
//CompareValidator1.ID = "CompareValidator1-" + WebControlID;
CompareValidator1.Attributes[
"name"
] =
"cmp-"
+ WebControlID;
CompareValidator1.Display =
this
.ValidatorDisplay;
CompareValidator1.ValidationGroup = ValidationGroup;
CompareValidator1.ValueToCompare = blComppareVal.value2;
CompareValidator1.Type = blComppareVal.Type;
var CompareOperator = blComppareVal.Operator;
CompareValidator1.Operator = blComppareVal.Operator;
//get the appropriate error message
string
CompareValErrorMessage =
string
.Empty;
//code to go get the error message, just hard code for example
string
RangeValErrorMessage =
"Compare Error"
;
CompareValidator1.ErrorMessage = CompareValErrorMessage;
CompareValidator1.Text = CompareValErrorMessage;
Controls.Add(CompareValidator1);
break
;
case
"RequiredFieldValidator"
:
var RequiredFieldValidator1 =
new
RequiredFieldValidator();
RequiredFieldValidator1.ControlToValidate = WebControlID;
RequiredFieldValidator1.ErrorMessage =
BusinessObj.Validators.ValidationResources.RequiredValueFailedValidation;
RequiredFieldValidator1.Text = RequiredFieldValidator1.ErrorMessage;
RequiredFieldValidator1.Display =
this
.ValidatorDisplay;
Controls.Add(RequiredFieldValidator1);
break
;
}
}
protected
override
void
Render(HtmlTextWriter writer)
{
base
.Render(writer);
foreach
(Control c
in
Controls)
{
int
index = Controls.IndexOf(c);
if
(Controls.IndexOf(c) == -1)
c.RenderControl(writer);
}
}
}

if
(Controls.IndexOf(c) == -1)
c.RenderControl(writer);
Should have a not in it.
if
(Controls.IndexOf(c) != -1)
c.RenderControl(writer);
With the asp.net controls I didn't have the conditional. I think when I tried with telerik I was getting doubles, so I wanted to see if the control had been rendered already. Still not sure if I need to do this check, but since I cannot get the ID to match, I can't tell yet.

I cannot spot any particular cause for the validators not being able to find the control. I also believe this issue might not be related to RadDateInput. Can you change the control to inherit from a simple TextBox control instead. Do you get the same behavior in this case, or does it not work when inheriting from TextBox again?
Veli
the Telerik team

Hi Veli,
Does it not work when inheriting from TextBox still?
thanks
Hi Veli,
To be able to advise you with, we would need to learn more about the approach you are taking and the expected behavior, please share more details on that. For instance, you can share the implementation that you have and describe the expected behavior as well as the behavior you are receiving at the moment. We will then inspect the code and share our findings.
Kind regards,
Attila Antal
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.