2010-09-01 12 views

Respuesta

4

En Forma:

if (_cached == null) 
{ 
    _cached = new List<TextBox>(); 

    foreach(var control in Controls) 
    { 
     TextBox textEdit = control as TextBox; 
     if (textEdit != null) 
     { 
      textEdit.ReadOnly = false; 
      _cached.Add(textEdit); 
     } 
    } 
} 
else 
{ 
    foreach(var control in _cached) 
    {    
     control .ReadOnly = false; 
    } 
} 

Agregar recursividad también (controles se puede colocar en otros controles (paneles)).

+0

Creo que almacenar en un caché aumenta el rendimiento. Sin embargo, tendrá que considerar la posibilidad de que el usuario actualice la caché. Su código tampoco itera a través de controles anidados (como los cuadros de texto colocados dentro de los paneles). En general, es una buena solución. –

+1

@Alex Essilfie Escribí: "Agregar recursión también" :), no hay menciones sobre la creación de códigos dinámicos para restablecer _cache (ver "en Formulario" no fuera de Formulario). Gracias. – garik

1
this.Enabled = false; 

Depende de lo que realmente esté haciendo, puede considerar colocar el control dentro de un panel y deshabilitarlo.

3

Debería poder escribir usted mismo una función de utilidad para hacer esto. Puede iterar sobre los controles del formulario y luego los controles secundarios de cada control recursivamente. Por ejemplo:

public static void SetEnableOnAllControls(Control parentControl, bool enable) 
{ 
    parentControl.Enabled = enable; 
    foreach (Control control in parentControl.Controls) 
     SetEnableOnAllControls(control, enable); 
} 

[...] 

// inside your form: 
SetEnableOnAllControls(this, false); 

Esto no toma cuidado de ToolStrip s, que no son controles. Podría escribir un método separado y similar para ellos.

Observe que lo anterior también deshabilita el formulario. Si no quieres eso, intente esto:

public static void SetEnableOnAllChildControls(Control parentControl, bool enable) 
{ 
    foreach (Control control in parentControl.Controls) 
    { 
     control.Enabled = enable; 
     SetEnableOnAllChildControls(control, enable); 
    } 
} 

si realmente se quiere decir la de sólo lectura propiedad, que sólo es relevante para cuadros de texto, intente esto:

public static void SetReadOnlyOnAllControls(Control parentControl, bool readOnly) 
{ 
    if (parentControl is TextBoxBase) 
     ((TextBoxBase) parentControl).ReadOnly = readOnly; 
    foreach (Control control in parentControl.Controls) 
     SetReadOnlyOnAllControls(control, readOnly); 
} 
+0

Podría poner un 'else' en ese último fragmento: los controles' TextBox' no son contenedores. –

+0

+1, la respuesta más completa. – Nobody

+0

votar abajo es una mala suerte. – garik

2

no he t probado esto, pero debería funcionar:

foreach (var textBox in this.Controls.OfType<TextBox>()) 
    textBox.ReadOnly = true; 

Editar: Esta no es una solución tan buena parece: ver el comentario de Timwi.

+0

El más correcto. Pero requiere .NET 3.5 – abatishchev

+1

① No tiene en cuenta los controles anidados, es decir, funciona solo en los controles de nivel superior; ② Debe usar 'TextBoxBase' para que también afecte a otros controles tipo cuadro de texto (por ejemplo,' RichTextBox'). – Timwi

+0

Buenos puntos Timwi, gracias. – Nobody

6

Escribir un método de extensión que reúne a los controles y los controles secundarios de tipo especificado:

public static IEnumerable<T> GetChildControls<T>(this Control control) where T : Control 
{ 
    var children = control.Controls.OfType<T>(); 
    return children.SelectMany(c => GetChildControls<T>(c)).Concat(children); 
} 

Gather cuadros de texto en el formulario (utilizar TextBoxBase para afectar RichTextBox, etc - @ solución de Timwi):

IEnumerable<TextBoxBase> textBoxes = this.GetChildControls<TextBoxBase>(); 

Ir a la colección y establecer como de solo lectura:

private void AreTextBoxesReadOnly(IEnumerable<TextBoxBase> textBoxes, bool value) 
{ 
    foreach (TextBoxBase tb in textBoxes) tb.ReadOnly = value; 
} 

Si lo desea, utilice el almacenamiento en caché - solución de @ igor

+0

+1 Esta parece ser la solución más reutilizable para mí. – Niki

2

Usaría la reflexión para verificar si el objeto de control genérico tiene una propiedad habilitada.

private static void DisableControl(Control control) 
{ 
    PropertyInfo enProp = control.GetType().GetProperty("Enabled"); 
    if (enProp != null) 
    { 
     enProp.SetValue(control, false, null); 
    } 

    foreach (Control ctrl in control.Controls) 
    { 
     DisableControl(ctrl); 
    } 
} 
0

acabo desarrollado una solución recursiva que se ocupa de cualquier tipo de control Web, usando un método estático simple y polymorphysm ASP.NET.

/// <summary> 
/// Handle "Enabled" property of a set of Controls (and all of the included child controls through recursivity) 
/// By default it disable all, making all read-only, but it can also be uset to re-enable everything, using the "enable" parameter 
/// </summary> 
/// <param name="controls">Set of controls to be handled. It could be the entire Page.Controls set or all of the childs of a given control (property "Controls" of any Control-derived class)</param> 
/// <param name="enable">Desired value of the property "enable" of each control. </param> 
public static void DisableControls(ControlCollection controls, bool enable = false) 
{ 
    foreach (Control control in controls) 
    { 
     var wCtrl = control as WebControl; 
     if (wCtrl != null) 
     { 
      wCtrl.Enabled = enable; 
     } 

     if (control.Controls.Count > 0) 
      DisableControls(control.Controls, enable); 
    } 
} 

/// <summary> 
/// Enable a set of Controls (and all of the included child controls through recursivity). 
/// Friendly name for DisableControls(controls, true), that achieve the same result. 
/// </summary> 
/// <param name="Controls">Set of controls to be handled. It could be the entire Page.Controls set or all of the childs of a given control (property "Controls" of any Control-derived class)</param> 
public static void EnableControls(ControlCollection controls) 
{ 
    DisableControls(controls, true); 
} 

Esto se prueba y se ve bastante rápido (menos de una milésima de segundo en un formulario web con 25+ controles para desactivar).

Si prefiere un método de extensión, creo que debería ser suficiente para cambiar la solución de la siguiente manera:

public static void DisableControls(this Control control, bool enable = false) 
{ 
    foreach (Control ctrl in control.Controls) 
    { 
     var wCtrl = ctrl as WebControl; 
     if (wCtrl != null) 
     { 
      wCtrl.Enabled = enable; 
     } 

     if (ctrl.Controls.Count > 0) 
      ctrl.DisableControls(enable); 
    } 
} 

public static void EnableControls(this Control control) 
{ 
    control.DisableControls(true); 
} 
Cuestiones relacionadas