Найти элемент управления в веб-форме - PullRequest
12 голосов
/ 06 марта 2009

У меня есть форма веб-контента, и мне нужен доступ к элементу управления внутри панели контента. Мне известны два способа доступа к элементу управления:

  1. TextBox txt = (TextBox)Page.Controls[0].Controls[3].Controls[48].Controls[6]
  2. Путем написания рекурсивной функции, которая просматривает все элементы управления.

Есть ли какой-нибудь другой более простой способ, поскольку Page.FindControl в этом случае не работает. Причина, по которой я спрашиваю, заключается в том, что мне кажется, что объект Page или объект Content Panel должны иметь метод для поиска дочернего элемента управления, но не может найти ничего подобного.

Ответы [ 2 ]

26 голосов
/ 06 марта 2009

Проблема в том, что FindControl () не пересекает определенные дочерние элементы управления, такие как шаблонный элемент управления. Если элемент управления, который вам нужен, находится в шаблоне, он не будет найден.

Таким образом, мы добавили следующие методы расширения для решения этой проблемы. Если вы не используете 3.5 или хотите избежать методов расширения, вы можете сделать из них универсальную библиотеку.

Теперь вы можете получить нужный элемент управления с помощью кода:

var button = Page.GetControl("MyButton") as Button;

Методы расширения делают рекурсивную работу за вас. Надеюсь, это поможет!

public static IEnumerable<Control> Flatten(this ControlCollection controls)
{
    List<Control> list = new List<Control>();
    controls.Traverse(c => list.Add(c));
    return list;
}

public static IEnumerable<Control> Flatten(this ControlCollection controls,     
    Func<Control, bool> predicate)
{
    List<Control> list = new List<Control>();
    controls.Traverse(c => { if (predicate(c)) list.Add(c); });
    return list;
}

public static void Traverse(this ControlCollection controls, Action<Control> action)
{
    foreach (Control control in controls)
    {
        action(control);
        if (control.HasControls())
        {
            control.Controls.Traverse(action);
        }
    }
}

public static Control GetControl(this Control control, string id)
{
    return control.Controls.Flatten(c => c.ID == id).SingleOrDefault();
}

public static IEnumerable<Control> GetControls(this Control control)
{
    return control.Controls.Flatten();
}
1 голос
/ 27 января 2015

Я бы хотел изменить вашу GetControls функцию на следующую:

public static T GetControl<T>(this Control control, string id) where T:Control
{
    var result = control.Controls.Flatten(c => (c.GetType().IsSubclassOf(typeof(T))) && (c.ID == id)).SingleOrDefault();
    if (result == null)
        return null;
    return result as T;
}

А потом,

public static Control GetControl(this Control control, string id)
{
    return control.GetControl<Control>(id);
}

Таким образом, вызывающая сторона будет называть что-то вроде:

var button = Page.GetControl<Button>("MyButton");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...