2010-09-01 9 views

risposta

4

In Form:

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; 
    } 
} 

Add ricorsione anche (controlli può essere collocato in altri controlli (pannelli)).

+0

Penso che l'archiviazione in una cache aumenti le prestazioni. Dovrai comunque considerare di consentire all'utente di aggiornare la cache. Il tuo codice non scorre anche attraverso i controlli annidati (come le caselle di testo posizionate all'interno dei pannelli). Nel complesso, è una buona soluzione. –

+1

@Alex Essilfie Ho scritto: "Aggiungi ricorsione anche" :), non ci sono menzioni sulla creazione di codice dinamico per reimpostare _cache (vedi "in Form" no out di Form). Grazie. – garik

1
this.Enabled = false; 

dipende da ciò che stai facendo in realtà, si potrebbe prendere in considerazione di mettere il controllo all'interno di un pannello e invalidante che.

3

Dovresti essere in grado di scrivere da solo una funzione di utilità per farlo. È possibile scorrere i controlli del modulo e quindi i controlli secondari di ciascun controllo ricorsivamente. Per esempio:

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); 

Ciò non prendersi cura di ToolStrip s, che non sono i controlli. Potresti scrivere un metodo separato, simile per quelli.

Si noti che quanto sopra disabilita anche il modulo stesso. Se non si desidera che, provate questo:

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

Se davvero si intende la ReadOnly proprietà, che è rilevante solo per TextBoxes, provate questo:

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

Potrebbe mettere un 'else' in quell'ultimo snippet: i controlli di' TextBox' non sono contenitori. –

+0

+1, la risposta più completa. – Nobody

+0

il voto negativo è una sfortuna. – garik

2

Mi rifugio' t testato questo, ma dovrebbe funzionare:

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

Modifica: Questa non è una buona soluzione, sembra: vedere il commento di Timwi.

+0

Il più corretto. Ma richiede .NET 3.5 – abatishchev

+1

① Non prende in considerazione i controlli annidati, cioè funziona solo sui controlli di primo livello; ② Dovrebbe usare 'TextBoxBase' in modo che influenzi anche altri controlli di tipo text box (ad esempio' RichTextBox'). – Timwi

+0

Buoni punti Timwi, grazie. – Nobody

6

Scrivi un metodo di estensione che raccoglie i comandi e controlli figlio del tipo specificato:

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); 
} 

Raccogliere TextBoxes sul modulo (utilizzare TextBoxBase per influenzare RichTextBox, ecc - @ soluzione Timwi):

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

Iterate thru collection e set only read:

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

Se vuoi - usa la cache - la soluzione di @ igor

+0

+1 Questa sembra la soluzione più riutilizzabile per me. – Niki

2

Vorrei usare la riflessione per verificare se l'oggetto Controllo generico ha una proprietà Enabled.

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

ho appena messo a punto una soluzione ricorsiva che gestisce ogni tipo di controllo Web, utilizzando un metodo statico semplice e ASP.NET polimorfismo.

/// <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); 
} 

Questo è testato e sembra abbastanza veloce (meno di un millisecondo in un modulo web con 25+ controllo per essere disattivato).

Se si preferisce un metodo di estensione, penso che dovrebbe essere sufficiente per cambiare la soluzione come segue:

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); 
} 
Problemi correlati