2010-09-01 7 views
5

Czy ktoś ma fragment kodu, aby wszystkie formanty (lub nawet wszystkie pola TextBox) w formularzu, który jest tylko do odczytu naraz, bez konieczności ustawiania każdej kontroli do odczytu- tylko indywidualnie?Wszystkie formanty na formularzu tylko do odczytu naraz

+0

@Raulp Nie sądzę „która jest” tutaj jest prawidłowa. Formularz nie jest przeznaczony tylko do odczytu, ale kontrole powinny być. – Breeze

Odpowiedz

4

W Rodzaj:

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

dodawania rekursji także (sterujące może być umieszczone w innych elementów sterujących (panele)).

+0

Myślę, że przechowywanie w pamięci podręcznej zwiększa wydajność. Będziesz jednak musiał rozważyć umożliwienie użytkownikowi odświeżenia pamięci podręcznej. Twój kod również nie wykonuje iteracji za pomocą zagnieżdżonych kontrolek (takich jak pola tekstowe umieszczone wewnątrz paneli). Ogólnie rzecz biorąc, jest to dobre rozwiązanie. –

+1

@Alex Essilfie Napisałem: "Dodaj rekurencję również" :), nie ma żadnych wzmianek o tworzeniu dynamicznego kodu, aby zresetować _cache (patrz "w formularzu" no out of Form). Dziękuję Ci. – garik

1
this.Enabled = false; 

zależy od tego co robi naprawdę, to może warto rozważyć wprowadzenie kontroli w centrali i wyłączenie tego.

3

Powinieneś być w stanie napisać sobie funkcję użyteczną, aby to zrobić. Możesz powtórzyć kontrolę nad formantem formularza, a następnie każde dziecko kontrolne kontroluje rekursywnie. Na przykład:

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

To nie zajmuje się ToolStrip s, które nie są kontrolami. Możesz napisać osobną, podobną do nich metodę.

Należy zauważyć, że powyższe wyłącza również sam formularz. Jeśli nie chcesz, spróbuj tego:

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

Jeśli naprawdę oznaczało ReadOnly nieruchomość, która ma znaczenie tylko dla tekstowych, spróbuj tego:

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

Można umieścić 'else' w tym ostatnim fragmencie: Kontrolki" TextBox "nie są kontenerami. –

+0

+1, najbardziej dokładna odpowiedź. – Nobody

+0

Głosowanie w dół to pech. – garik

2

I haven” t testowane, ale to powinno działać:

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

Edit: to nie jest tak dobrym rozwiązaniem wydaje: patrz komentarz Timwi użytkownika.

+0

Najbardziej poprawne. Ale wymaga .NET 3.5 – abatishchev

+1

① Nie uwzględnia zagnieżdżonych elementów sterujących, tzn. Działa tylko na elementach sterujących najwyższego poziomu; ② Powinien używać 'TextBoxBase', aby wpływał także na inne kontrolki tekstowe (np.' RichTextBox'). – Timwi

+0

Dobre punkty Timwi, dziękuję. – Nobody

6

Napisz metodę rozszerzenia, które ma żadnych elementów sterujących i formantów podrzędnych z określonego typu:

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

zbierać tekstowych na formularzu (wykorzystać TextBoxBase wpłynąć RichTextBox, etc - @ rozwiązania Timwi za):

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

Powtórz iterację i ustaw tylko do odczytu:

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

Jeśli chcesz - użyj buforowania - @ igor's solution

+0

+1 To wydaje mi się najbardziej odpowiednie rozwiązanie. – Niki

2

Chciałbym użyć refleksji, aby sprawdzić, czy ogólny obiekt Control ma właściwość 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

właśnie opracowali rozwiązanie, które obsługuje rekurencyjną jakiejkolwiek kontroli sieci, wykorzystując prostą metodę statyczną i ASP.NET polymorphysm.

Zostało to przetestowane i wygląda dość szybko (mniej niż milisekundę w formularzu sieciowym z wyłączonymi ponad 25 kontrolkami).

Jeśli wolisz metodę rozszerzenia, myślę, że to powinno wystarczyć, aby zmienić rozwiązanie następująco:

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); 
} 
Powiązane problemy