2009-03-06 4 views
12

У меня есть форма веб-контента и вам нужно получить доступ к элементу управления внутри панели содержимого. Я знаю, что из двух способов доступа управления:Найти элемент управления в веб-форме

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

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

ответ

26

Проблема заключается в том, что 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

Вау, это должно быть p искусство Рамки! – Marcel

0

Я хотел бы изменить свою 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"); 
Смежные вопросы