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.
