Шаблонный пользовательский элемент управления с двумя шаблонами, как найти элемент управления в другом шаблоне для свойств, для которых требуется идентификатор элемента управления - PullRequest
1 голос
/ 12 сентября 2011

У меня есть шаблонный пользовательский элемент управления с двумя шаблонами, и все работает, кроме установки идентификаторов для таких вещей, как 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;
    }
}

Спасибо залюбая помощь с этой надоедливой проблемой.

Крис

1 Ответ

0 голосов
/ 31 декабря 2012

Для ControlToValidate вы можете использовать ValidationPropertyAttribute в определении класса элемента управления InputTemplate. Просто обновите ваш код как:

//"Text" is the name of the Property which returns the value to validate
[ValidationProperty("Text")] 
public class InputTemplate
{
    ...
    public string Text { set { txtValue.Text = value; } get { return txtValue.Text } }
}

Теперь в своем коде вы можете установить для свойства RequiredFieldValidator ControlToValidate идентификатор пользовательского элемента управления: например. RequiredFieldValidator1.ControlToValidate = InputTemplate1.ID;

Что касается AssociatedControlID для метки, я еще не понял этого.

Best of Luck,

Shawn

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...