2011-01-07 3 views
1

У меня есть ASP.Net MasterPage с элементом PlaceHolder. Содержимое PlaceHolder можно просматривать в двух режимах: чтение-запись и только чтение.Выборочное отключение элементов WebControl

Чтобы реализовать только чтение, я хотел отключить все входы внутри PlaceHolder.
Я решил сделать это, рекурсивным образом перейдя через коллекцию управления PlaceHolder, найдя все те, которые наследуются от WebControl, и установив control.Enabled = false;.

Вот что я изначально писал:

private void DisableControls(Control c) 
{ 
    if (c.GetType().IsSubclassOf(typeof(WebControl))) 
    { 
     WebControl wc = c as WebControl; 
     wc.Enabled = false; 
    } 

    //Also disable all child controls. 
    foreach (Control child in c.Controls) 
    { 
     DisableControls(child); 
    } 
} 

Это работало отлично, и все элементы управления отключаются ... Но то требование изменилось;)
сейчас, мы хотим, чтобы отключить все указательные кроме из них которые имеют определенный CssClass.

Итак, моя первая попытка в новой версии:

private void DisableControls(Control c) 
{ 
    if (c.GetType().IsSubclassOf(typeof(WebControl))) 
    { 
     WebControl wc = c as WebControl; 
     if (!wc.CssClass.ToLower().Contains("someclass")) 
      wc.Enabled = false; 
    } 

    //Also disable all child controls. 
    foreach (Control child in c.Controls) 
    { 
     DisableControls(child); 
    } 
} 

Теперь я попал проблему. Если у меня есть (например) <ASP:Panel>, который содержит <ASP:DropDownList>, и я хочу, чтобы DropDownList был включен, тогда это не работает.

Я вызываю DisableControls на Panel и отключается. Затем он перебирает дочерние элементы и вызывает DisableControls в DropDownList и оставляет его включенным (как предполагалось). Однако, поскольку панель отключена, когда страница отображается, все внутри метки <div> отключено!

Можете ли вы подумать об этом? Я думал об изменении c.GetType().IsSubclassOf(typeof(WebControl)) до c.GetType().IsSubclassOf(typeof(SomeParentClassThatAllInputElementsInheritFrom)), но я не могу найти что-нибудь подходящее!

ответ

2

Вы только хотите отключить элементы управления вводом, поэтому ваш код является слишком общим. Сделайте что-то вроде этого:

if (IsInputControl(wc) && !wc.CssClass.ToLower().Contains("someclass")) 
      wc.Enabled = false; 

и создать функцию IsInputControl:

bool isInputControl(WebControl ctl) { 
    if (ctl is TextBox || 
     ctl is DropDownList || 
     ctl is CheckBox || 
     ...) { 
     return true; 
    } else { 
     return false; 
    } 
} 

Я не знаю ни одного общего имущества WebControl, который идентифицирует его как элемент управления вводом, хотя, но не что многие типы, поэтому это не должно быть слишком большой сделкой для этого.

+0

Да, я думал о том, чтобы сделать что-то подобное ... Я беспокоюсь о том, чтобы этот список типов был правильным/полным. Если я смогу найти более общий метод определения «входных» элементов, тогда я это сделаю. Если нет, тогда я помету ваш как ответ :) – NeilD

+0

Я уже делал что-то подобное раньше, я никогда не нашел его, а не сказал, что его не существует. Я делал это для контроллера общей цели, я создал категории элементов управления (InputControls, Validators, InputControls_WithHiddenFields). Я не думаю, что скрытые поля важны для вашей ситуации, но они сделали для моих, и они не являются WebControls (несмотря на то, что они находятся в пространстве имен System.Web.UI.WebControls), что делает его еще более уродливым. –

+0

Я закончил делать обратное тому, что вы предложили. Вместо этого я написал функцию «IsContainerControl» ... Список возможных контейнеров кажется короче, чем список возможных элементов управления вводом! На данный момент я исключил элементы управления Panel, но я ожидаю, что этот список будет расти по мере того, как будет идентифицировано больше. – NeilD