2010-09-01 19 views
5

पर एक फॉर्म पर सभी नियंत्रण बनाएं, क्या किसी के पास सभी नियंत्रण (या यहां तक ​​कि सभी टेक्स्टबॉक्स) को एक फॉर्म में कोड बनाने का एक टुकड़ा है जो केवल पढ़ने के लिए प्रत्येक नियंत्रण को सेट किए बिना पढ़ा जाता है- केवल व्यक्तिगत रूप से?एक बार

+0

@Raulp मुझे नहीं लगता कि "है जो" यहाँ सही है। फॉर्म केवल पढ़ने के लिए नहीं है, लेकिन नियंत्रण होना चाहिए। – Breeze

उत्तर

4

प्रपत्र:

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

जोड़ें प्रत्यावर्तन भी (नियंत्रण अन्य नियंत्रण (पैनल) में रखा जा सकता है)।

+0

मुझे लगता है कि एक कैश में भंडारण प्रदर्शन को बढ़ाता है। हालांकि आपको उपयोगकर्ता को कैश रीफ्रेश करने की अनुमति देने पर विचार करना होगा। आपका कोड नेस्टेड नियंत्रणों के माध्यम से भी पुनरावृत्ति नहीं करता है (जैसे पैनलों के अंदर रखे टेक्स्टबॉक्स)। कुल मिलाकर, यह एक अच्छा समाधान है। –

+1

@ एलेक्स एसिल्फी मैंने लिखा: "रिकर्सन भी जोड़ें" :), _cache को रीसेट करने के लिए गतिशील कोड निर्माण के बारे में कोई उल्लेख नहीं है (फ़ॉर्म में "फॉर्म में" फॉर्म में देखें)। धन्यवाद। – garik

1
this.Enabled = false; 

वास्तव में आप जो कर रहे हैं उस पर निर्भर करता है, तो आप नियंत्रण को एक पैनल में डालने और इसे अक्षम करने पर विचार करना चाहेंगे।

3

आपको ऐसा करने के लिए स्वयं को उपयोगिता कार्य लिखने में सक्षम होना चाहिए। आप फॉर्म के नियंत्रणों पर फिर से सक्रिय हो सकते हैं और फिर प्रत्येक नियंत्रण के बाल नियंत्रण को पुन: सक्रिय कर सकते हैं। उदाहरण के लिए:

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

यह ToolStrip एस का ख्याल नहीं रखता है, जो नियंत्रण नहीं हैं। आप उन लोगों के लिए एक अलग, समान विधि लिख सकते हैं।

ध्यान दें कि उपर्युक्त फॉर्म भी स्वयं को अक्षम करता है। आपको लगता है कि नहीं करना चाहते हैं, इस कोशिश: क्या तुम सच में ReadOnly संपत्ति है, जो बक्सें के लिए ही प्रासंगिक है, तो मतलब

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

, इस प्रयास करें:

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

उस अंतिम स्निपेट में 'else' डाल सकता है: 'टेक्स्टबॉक्स' नियंत्रण कंटेनर नहीं हैं। –

+0

+1, सबसे गहन जवाब। मतदान के नीचे – Nobody

+0

एक दुर्भाग्य है। – garik

2

मैं हेवन ' टी ने इसका परीक्षण किया, लेकिन इसे काम करना चाहिए:

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

संपादित करें: ऐसा कोई अच्छा समाधान नहीं है: ऐसा लगता है कि टिमवी की टिप्पणी देखें।

+0

सबसे सही। लेकिन .NET 3.5 – abatishchev

+1

की आवश्यकता है ① खाते में नेस्टेड नियंत्रण नहीं लेते हैं, यानी केवल शीर्ष-स्तरीय नियंत्रणों पर काम करता है; ② 'टेक्स्टबॉक्सबॉक्स' का उपयोग करना चाहिए ताकि यह अन्य टेक्स्ट-बॉक्स-जैसे नियंत्रणों को भी प्रभावित करे (उदा। 'RichTextBox')। – Timwi

+0

अच्छा अंक Timwi, धन्यवाद। – Nobody

6

एक विस्तार विधि है जो निर्दिष्ट प्रकार के नियंत्रण और बच्चे नियंत्रण बटोरता लिखें:

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

फार्म पर बक्सें इकट्ठा (TextBoxBase का उपयोग को प्रभावित करने के RichTextBox, आदि - @ Timwi के समाधान):

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

संग्रह के माध्यम से Iterate और केवल पढ़ने के लिए सेट:

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

यदि चाहें - कैशिंग का उपयोग करें - @ igor के समाधान

+0

+1 यह मेरे लिए सबसे पुन: प्रयोज्य समाधान लगता है। – Niki

2

मैं यह देखने के लिए प्रतिबिंब का उपयोग करूंगा कि जेनेरिक कंट्रोल ऑब्जेक्ट में एक सक्षम संपत्ति है या नहीं।

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

मैं सिर्फ एक पुनरावर्ती समाधान है कि वेब नियंत्रण के किसी भी प्रकार संभालती विकसित की है, एक सरल स्थिर विधि और ASP.NET polymorphysm का उपयोग कर।

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

यह परीक्षण किया जाता है और काफी तेजी से दिखता है (25+ नियंत्रणों के साथ एक वेब फॉर्म में मिलीसेकंड से भी कम)।

आप एक विस्तार विधि पसंद करते हैं, मुझे लगता है कि इस प्रकार के रूप में यह समाधान बदलने के लिए पर्याप्त होना चाहिए:

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