0

I'm building a WPF app with a StackPanel of Grids with TextBoxes in them. I need a list of all the TextBoxes. How do I reach two levels deep using Children.OfType() function?

Already tried: https://stackoverflow.com/a/10279201/9985476 but didn't seem to work. Maybe I implemented it wrong?

Sample code:

  <StackPanel x:Name="addEmployees">
    <Grid>
      <TextBox Text="" />
    </Grid>
    <Grid>
      <TextBox Text="" />
    </Grid>
    <Grid>
      <TextBox Text="" />
    </Grid>
  <StackPanel />

In my code behind i tried something of this sort:

private IEnumerable<TextBox> addEmployeesTB = addEmployees.Children.OfType<Grid>().Children.OfType<TextBox>();

But i get: CS1061 C# does not contain a definition for 'Children' and no accessible extension method 'Children' accepting a first argument of type could be found (are you missing a using directive or an assembly reference?)

mac501
  • 37
  • 5
  • You're working with wpf in a very inefficient way. Making things hard for yourself. Instead of adding controls in code you should bind a collection of viewmodels and template that out into ui. Repeated controls - think itemscontrol. You then don't need to find the children of the child you first added... You just work with the data in the bound collection. Usually an observablecollection. Everyone uses mvvm because it's easily the best way to work. It will seem strange at first but that's just because it's different. – Andy May 11 '19 at 09:40

1 Answers1

0

addEmployees.Children.OfType<Grid>() gives you an IEnumerable of Grid, not a single Grid.

So we can't just "dot" them out. Assuming every list of Grid has a number of TextBox children, we have to flatten them out with LINQ SelectMany.

This is how SelectMany works. You have a list of Grid, and each Grid has a list of TextBox.

Grid1
    TextBox1
    TextBox2
Grid2
    TextBox3
Grid3
    TextBox4
    TextBox5

We can use SelectMany to turn them into

TextBox1
TextBox2
TextBox3
TextBox4
TextBox5

Here's my attempt at your code:

private IEnumerable<TextBox> addEmployeesTB = addEmployees.Children.OfType<Grid>()
            .SelectMany(grid => grid.Children.OfType<TextBox>())
            .ToList();

It should look like this: enter image description here

Here is LINQ SelectMany documentation.

Please let me know if it works.

Nam Le
  • 568
  • 5
  • 12