2009-03-02 19 views
11

में सभी टेक्स्टबॉक्स नियंत्रण खोजने के लिए जेनेरिक विधि मेरे पास पृष्ठ पर कई सिल्वरलाइट नियंत्रण हैं और टेक्स्टबॉक्स के सभी नियंत्रणों से पूछना चाहते हैं और यह काम कर रहे हैं।सिल्वरलाइट

अब सिल्वरलाइट फॉर्म मैं पर काम कर रहा हूं में अधिक टेक्स्टबॉक्स नियंत्रण जोड़े गए हैं। तो जब मैं अगर किसी पाठ बॉक्स नियंत्रण एक मूल्य है देखने के लिए परीक्षण, मैं कर सकता:

if (this.TextBox.Control.value.Text() != String.Empty) 
{ 
    // do whatever 
} 

लेकिन मैं नहीं बल्कि लचीला अगर है कि मैं इस किसी भी सिल्वरलाइट फार्म पर ध्यान दिए बिना पाठ बॉक्स नियंत्रण की संख्या का उपयोग कर सकते हैं होगा मैं की है।

कोई विचार है कि मैं ऐसा करने के बारे में कैसे जाऊंगा?

उत्तर

10

ऐसा लगता है कि आप एक पुनरावर्ती दिनचर्या नीचे GetTextBoxes तरह की जरूरत है:

void Page_Loaded(object sender, RoutedEventArgs e) 
{ 
    // Instantiate a list of TextBoxes 
    List<TextBox> textBoxList = new List<TextBox>(); 

    // Call GetTextBoxes function, passing in the root element, 
    // and the empty list of textboxes (LayoutRoot in this example) 
    GetTextBoxes(this.LayoutRoot, textBoxList); 

    // Now textBoxList contains a list of all the text boxes on your page. 
    // Find all the non empty textboxes, and put them into a list. 
    var nonEmptyTextBoxList = textBoxList.Where(txt => txt.Text != string.Empty).ToList(); 

    // Do something with each non empty textbox. 
    nonEmptyTextBoxList.ForEach(txt => Debug.WriteLine(txt.Text)); 
} 

private void GetTextBoxes(UIElement uiElement, List<TextBox> textBoxList) 
{ 
    TextBox textBox = uiElement as TextBox; 
    if (textBox != null) 
    { 
     // If the UIElement is a Textbox, add it to the list. 
     textBoxList.Add(textBox); 
    } 
    else 
    { 
     Panel panel = uiElement as Panel; 
     if (panel != null) 
     { 
      // If the UIElement is a panel, then loop through it's children 
      foreach (UIElement child in panel.Children) 
      { 
       GetTextBoxes(child, textBoxList); 
      } 
     } 
    } 
} 

का दृष्टांत बक्सें की एक खाली सूची। अपने पृष्ठ पर रूट नियंत्रण में गुजरने वाले GetTextBoxes को कॉल करें (मेरे मामले में, यह है। LayoutRoot), और GetTextBoxes को उस यूआई तत्व के माध्यम से रिकर्सिव लूप करना चाहिए जो उस नियंत्रण के वंशज हैं, यह देखने के लिए परीक्षण करें कि यह टेक्स्टबॉक्स है या नहीं सूची में), या एक पैनल, जिसके माध्यम से पुनर्विक्रय करने के लिए इसके स्वयं के वंशज हो सकते हैं।

उम्मीद है कि मदद करता है। :)

+0

बहुत धन्यवाद! यह निश्चित रूप से मैं क्या देख रहा था। अब मुझे यह देखने की ज़रूरत है कि क्या मैं अधिक जानकारी निकालने के लिए UIElement क्लास कर सकता हूं। (यानी नियंत्रण x: यदि संभव हो तो नाम) – coson

+0

मुझे नहीं लगता कि आप 'स्क्रॉल व्यूअर' को 'पैनल' के रूप में डाला जा सकता है, इसलिए यदि आपको एक बच्चे को प्राप्त करने की आवश्यकता हो, तो आपको एक और 'अन्य' । – mbomb007

3

अपने शीर्ष सबसे पैनल से आप यह कर सकते हैं (मेरे ग्रिड ContentGrid कहा जाता है)

var textBoxes = this.ContentGrid.Children.OfType<TextBox>(); 
var nonEmptyTextboxes = textBoxes.Where(t => !String.IsNullOrEmpty(t.Text)); 
foreach (var textBox in nonEmptyTextboxes) 
{ 
    //Do Something 
} 

हालांकि यह केवल बक्सें कि तत्काल बच्चे हैं मिल जाएगा। नीचे की तरह कुछ प्रकार की रिकर्सन मदद करेगी, लेकिन मुझे लगता है कि एक बेहतर तरीका होना चाहिए।

private List<TextBox> SearchForTextBoxes(Panel panel) 
{ 
    List<TextBox> list = new List<TextBox>(); 
    list.AddRange(panel.Children.OfType<TextBox>() 
     .Where(t => !String.IsNullOrEmpty(t.Text))); 

    var panels = panel.Children.OfType<Panel>(); 
    foreach (var childPanel in panels) 
    { 
     list.AddRange(SearchForTextBoxes(childPanel)); 
    } 
    return list; 
} 
+0

यह निश्चित रूप से सही दिशा में एक कदम है। नियंत्रण के बारे में जानकारी प्राप्त करने के लिए प्रतिबिंब का उपयोग करने का कोई तरीका है यदि यह एक निश्चित नियंत्रण प्रकार है? – coson

+0

आपका क्या मतलब है? ओएफटी टाइप एक्सटेंशन विधि केवल निर्दिष्ट प्रकार के नियंत्रण लौटाएगी। और वे सही टाइप किया जाएगा। आप किस प्रकार की जानकारी के बाद हैं? – Ray

14

मैं पहले से ही इस मुद्दे का सामना करना पड़ा है और उसे यहां सूचित किया है:

IEnumerable<DependencyObject> GetChildrenRecursively(DependencyObject root) 
{ 
    List<DependencyObject> children = new List<DependencyObject>(); 
    children.Add(root); 
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++) 
     children.AddRange(GetChildrenRecursively(VisualTreeHelper.GetChild(root, i))); 

    return children; 
} 

को इस तरह इस विधि का उपयोग करें: http://megasnippets.com/en/source-codes/silverlight/Get_all_child_controls_recursively_in_Silverlight

यहाँ आप एक सामान्य विधि सभी बक्सें है VisualTree में रिकर्सिवली को खोजने के लिए सभी बक्सें लगता है:

var textBoxes = GetChildrenRecursively(LayoutRoot).OfType<TextBox>(); 
+0

वीबी.Net: सार्वजनिक साझा फ़ंक्शन GetChildsRecursive (ByVal रूट के रूप में निर्भरता ऑब्जेक्ट) के रूप में IENumerable (निर्भरता ऑब्जेक्ट) के रूप में नई सूची (निर्भरता ऑब्जेक्ट) के रूप में मिली मिली। जोड़ें (रूट) के रूप में मैं Integer = 0 VisualTreeHelper.GetChildrenCount (रूट) - 1 मिला। AddRange (GetChildsRecursive (VisualTreeHelper.GetChild (रूट, i))) अगला रिटर्न मिला अंतिम फंक्शन – Christoph

3

Scott'sinitial idea लिया और इसका विस्तार इतना है कि यह

  1. जेनिक्स का उपयोग करता है, इसलिए यह आसानी से कई नियंत्रण प्रकारों के साथ copes।
  2. अधिक कंटेनर प्रकार का समर्थन करता है। मेरे WP7 में मुझे पैनोरमा, स्क्रॉल व्यूअर आदि का समर्थन करने की आवश्यकता थी ... जो पैनल नहीं हैं। तो यह उनके लिए समर्थन की अनुमति देता है।
  3. सबसे बड़ी समस्या यह है कि स्ट्रिंग की तुलना, विशेष रूप से पैनल और व्युत्पन्न वस्तुओं पर।

कोड:

private static void GetControls<T>(UIElement uiElement, List<T> controlList) where T : UIElement 
{ 
    var frameworkFullName = uiElement.GetType().FullName; 
    if (frameworkFullName == typeof(T).FullName) 
    { 
     controlList.Add(uiElement as T); 
     return; 
    } 

    if (frameworkFullName == typeof(Panel).FullName || 
     frameworkFullName == typeof(Grid).FullName || 
     frameworkFullName == typeof(StackPanel).FullName) 
    { 
     foreach (var child in (uiElement as Panel).Children) 
     { 
      GetControls(child, controlList); 
     } 
     return; 
    } 

    if (frameworkFullName == typeof(Panorama).FullName) 
    { 
     foreach (PanoramaItem child in (uiElement as Panorama).Items) 
     { 
      var contentElement = child.Content as FrameworkElement; 
      if (contentElement != null) 
      { 
       GetControls(contentElement, controlList); 
      } 
     } 
     return; 
    } 

    if (frameworkFullName == typeof(ScrollViewer).FullName) 
    { 
     var contentElement = (uiElement as ScrollViewer).Content as FrameworkElement; 
     if (contentElement != null) 
     { 
      GetControls(contentElement, controlList); 
     } 
     return; 
    } 
} 
+0

ग्रिड विरासत पैनल –

1

विचारों के लिए इसी तरह के तर्क से ऊपर भी एक "सामग्री" के साथ नियंत्रण संभाल करने TabItems और Scrollviewers जहां बच्चों को एक निचले स्तर पर एम्बेड किया जा सकता है की तरह जोड़कर देखते हैं।सभी बच्चों को ढूंढता है:

IEnumerable<DependencyObject> GetControlsRecursive(DependencyObject root) 
    { 
     List<DependencyObject> elts = new List<DependencyObject>(); 
     elts.Add(root); 
     string type = root.GetType().ToString().Replace("System.Windows.Controls.", ""); 
     switch (root.GetType().ToString().Replace("System.Windows.Controls.", "")) 
     { 
      case "TabItem": 
       var TabItem = (TabItem)root; 
       elts.AddRange(GetControlsRecursive((DependencyObject)TabItem.Content)); 
       break; 
      case "ScrollViewer": 
       var Scroll = (ScrollViewer)root; 
       elts.AddRange(GetControlsRecursive((DependencyObject) Scroll.Content)); 
       break; 
      default: //controls that have visual children go here 
       for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++) elts.AddRange(GetControlsRecursive(VisualTreeHelper.GetChild(root, i))); 
       break; 
     } 
     return elts; 
    }