I have several Silverlight controls on a page and want query all the controls that are of type TextBox and have that working.
Now the Silverlight form I'm working on could have more TextBox controls added. So when I test to see if a TextBox control has a value, I could do:
if (this.TextBox.Control.value.Text() != String.Empty)
{
// do whatever
}
but I'd rather have if flexible that I can use this on ANY Silverlight form regardless of the number of TextBox controls I have.
Any ideas on how I would go about doing that?
I have already faced this issue and notify it here : http://megasnippets.com/en/source-codes/silverlight/Get_all_child_controls_recursively_in_Silverlight
Here you have a generic method to find recursively in the VisualTree all TextBoxes:
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;
}
Use this method like this to find all TextBoxes:
var textBoxes = GetChildrenRecursively(LayoutRoot).OfType<TextBox>();
It sounds like you need a recursive routine like GetTextBoxes below:
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);
}
}
}
}
Instantiate an empty list of TextBoxes. Call GetTextBoxes, passing in the root control on your page (in my case, that's this.LayoutRoot), and GetTextBoxes should recursively loop through every UI element that is a descendant of that control, testing to see if it's either a TextBox (add it to the list), or a panel, that might have descendants of it's own to recurse through.
Hope that helps. :)
From your top most panel you can do this (my grid is called ContentGrid)
var textBoxes = this.ContentGrid.Children.OfType<TextBox>();
var nonEmptyTextboxes = textBoxes.Where(t => !String.IsNullOrEmpty(t.Text));
foreach (var textBox in nonEmptyTextboxes)
{
//Do Something
}
However this will only find the textboxes that are immediate children. Some sort of recursion like below would help, but I'm thinking there must be a better way.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With