У меня есть шаблонный пользовательский элемент управления с двумя шаблонами, и все работает, кроме установки идентификаторов для таких вещей, как AssociatedControlID или ControlToValidate для элементов управления, которые существуют в другом шаблоне.
Я понимаю, что они существуют в двух разных контейнерах именования, что не позволяет им находить друг друга, поэтому в приведенном ниже коде установка AssociatedControlID не работает только с идентификатором элемента управления.Есть ли какой-то трюк для установки этого декларативно, или мне придется использовать FindControl и установить его в коде позади?
Вот мой макет управления:
<uc1:Field ID="paramName" runat="server">
<LabelTemplate >
<asp:Label ID="lblName" AssociatedControlID="txtValue" runat="server" >Label Text:</asp:Label>
</LabelTemplate>
<InputTemplate>
<asp:TextBox ID="txtValue" runat="server" MaxLength="30"></asp:TextBox>
</InputTemplate>
</uc1:Field>
РЕДАКТИРОВАТЬ 1: Я даже не могу заставить его работать, устанавливая его в коде позади.Я пытался установить AssociatedControlID в .ID, .ClientID, .UniqueID, я всегда забываю, что требуется, поэтому я попробовал их все.Я также попытался найти элемент управления из FindControl.Я могу найти его от родителя элемента управления, но не от родителя родителя.Это очень странно.
РЕДАКТИРОВАТЬ 2: Я нашел частичное решение.Он не работает для AssociatedControlID, но он работает для ControlToValidate, что на самом деле для меня важнее.Вот обходной путь: в вашем классе контейнеров вы должны переопределить FindControl и сделать так, чтобы он указывал на два уровня.Затем вам нужно будет сделать свой собственный FindControl, как я пытался Parent.Parent.FindControl, и он все еще не нашел элементы управления, я не совсем понимаю, почему, поэтому у меня есть метод расширения для перечисления всех элементов управления в коллекции элементов управления.Я также не знаю, почему он не работает с AssociatedControlID для меток.Может быть, внутренне он вызывает FindControl по-разному.
Я все еще чувствую, что упускаю что-то простое.
/// <summary>
/// This is a hack to get the validators in the label template to see the controls in the input template
/// just don't name any controls in the two templates the same thing
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public override Control FindControl(string id)
{
if (Parent == null && Parent.Parent == null)
{
return base.FindControl(id);
}
return Parent.Parent.Controls.All().Where(x => x.ID == id).FirstOrDefault();
}
Вот метод всех расширений:
public static IEnumerable<Control> All(this ControlCollection controls)
{
foreach (Control control in controls)
{
foreach (Control grandChild in control.Controls.All())
yield return grandChild;
yield return control;
}
}
Спасибо залюбая помощь с этой надоедливой проблемой.
Крис