0

I'm trying to dynamically add a RequiredFieldValidator to a RadioButtonList in a repeater, but it fails with the error:

Unable to find control id 'rblAccessory_40' referenced by the 'ControlToValidate' property of ''. 

The code for this section is:

            if ((e.Item.ItemType != ListItemType.Header) && (e.Item.ItemType != ListItemType.Footer))
        {

            Label lblAccID = (Label)e.Item.FindControl("lblAccID");
            RadioButtonList rblCondition = (RadioButtonList)e.Item.FindControl("rblCondition");

            rblCondition.ID = "rblAccessory_" + lblAccID.Text;


            if (conditionList.Count() > 0)
            {
                RequiredFieldValidator rfv = new RequiredFieldValidator();
                rfv.ControlToValidate = "rblAccessory_" + lblAccID.Text;
                rfv.ErrorMessage = "Please complete the accessories section";
                pnlValidation.Controls.Add(rfv);

                rblCondition.DataSource = conditionList;
                rblCondition.DataValueField = "id";
                rblCondition.DataBind();
            }
            foreach (ListItem li in rblCondition.Items)
            {
                li.Text = "";
                li.Value = "AccessoryID_" + lblAccID.Text + "-ConditionID_" + li.Value;
            }
        }
    }

It is definitely finding the RadioButtonList (rblCondition) because the data is binding correctly at this point:

                rblCondition.DataSource = conditionList;
                rblCondition.DataValueField = "id";
                rblCondition.DataBind();

So I don't understand why the error says it is unable to find the control ID.

I've tried specifying the control ID manually, as below:

rfv.ControlToValidate = "rblAccessory_" + lblAccID.Text;

and have also tried:

rfv.ControlToValidate = rblCondition.ID;

lblAccID is a hidden text field used to store the ID of the row in the repeater.

Ben
  • 4,281
  • 8
  • 62
  • 103
  • Updated my answer. I ran into a very similar problem recently and below is how I solved it. I'm assuming you're creating your controls in the `ItemCreated` event handler. – MushinNoShin Jul 13 '13 at 18:35

2 Answers2

2
  1. Assign the control to validate property AFTER the ItemCreated event. I know this sounds weird, how would you still have the reference to the dynamically created control? I've gotten around this by keeping a reference to a List<Action> reference which I add things to during ItemCreated to be executed later.

In your control class you'll declare your List<Action> object:

List<Action> deferringControlToValidateUntilPreRender = new List<Action>();

Inside the ItemCreated event you'll have a line that looks like:

deferringControlToValidateUntilPreRender.Add(() => rfv.ControlToValidate = rblCondition.UniqueID);

And then, later, perhaps in PreRender:

foreach(var deferredAction in deferringControlToValidateUntilPreRender) action();

MushinNoShin
  • 4,695
  • 2
  • 32
  • 46
  • Generally I would suggest using UniqueID instead of ClientID. There's less things that can go wrong when using UniqueID, at least that's what my experience has been so far. – MushinNoShin Jul 13 '13 at 18:34
0

Since the RequiredFieldValidator is client-side code, you need to use the client id of the control. Like this:

rfv.ControlToValidate = rblCondition.ClientID;

Some more information from MSDN if you are interested:

Control.ClientIDMode Property

Also, an SO discussion on the differences between ClientID and UniqueID (as referenced in @MushinNoShin's answer, which, IMHO, is incorrect):

Why is there a difference between ClientID and UniqueID?

Community
  • 1
  • 1
Shai Cohen
  • 6,074
  • 4
  • 31
  • 54