Search code examples
c#wpfdynamicwpf-grid

How to dynamically create and modify a new Grid row elements?


I'm just starting a new WPF app. I have a grid and want to create the rows dynamically (pressing a button for example) and then create TextView/ProgressBar inside this row.

I already searched how to create the gridrows programatically. But in every solution, i can't access what's inside and it becomes useless.

<Grid x:Name="MainGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Button x:Name="AddLineButton" Content="Click to add a new line" Click="AddLineButton_Click"/>
    <Grid x:Name="beGrid" Grid.Row="1">
<!-- I need my new rows here -->
    </Grid>
</Grid>
int i = 0; //nb of rows

    private void AddLineButton_Click(object sender, RoutedEventArgs e)
    {
        Create_line();
        i++;
    }

    private void Create_line()
    {
        RowDefinition gridRow = new RowDefinition();
        gridRow.Height = new GridLength(1, GridUnitType.Star);
        beGrid.RowDefinitions.Add(gridRow);
        StackPanel stack = new StackPanel();
        stack.Orientation = Orientation.Horizontal;
        TextBlock textBlock = new TextBlock();
        textBlock.Text = "Question";
        textBlock.Name = "Test" + i.ToString();
        stack.Children.Add(textBlock);
        beGrid.Children.Add(stack);
        Grid.SetRow(stack, i);
    }

I can't access a previously created element.

AFTER ANSWER :

    private void Create_line()
    {
        RowDefinition gridRow = new RowDefinition();
        gridRow.Height = new GridLength(1, GridUnitType.Star);
        beGrid.RowDefinitions.Add(gridRow);
        StackPanel stack = new StackPanel();
        stack.Orientation = Orientation.Horizontal;
        TextBlock textBlock = new TextBlock();
        textBlock.Text = "Question";
        textBlock.Name = "Test" + i.ToString();
        RegisterName(textBlock.Name, textBlock);
        stack.Children.Add(textBlock);
        beGrid.Children.Add(stack);
        Grid.SetRow(stack, i);
    }

To get the created TextBlock : var text = (TextBlock)FindName("Test"+i.ToString());


Solution

  • you can store all created StackPanel in a List.

    private void AddLineButton_Click(object sender, RoutedEventArgs e)
    {
        Create_line();
    }
    
    List<StackPanel> items;
    
    private void Create_line()
    {
        RowDefinition gridRow = new RowDefinition();
        gridRow.Height = new GridLength(1, GridUnitType.Star);
        beGrid.RowDefinitions.Add(gridRow);
    
        StackPanel stack = new StackPanel();
        stack.Orientation = Orientation.Horizontal;
    
        int i = items.Count + 1;
        TextBlock textBlock = new TextBlock();
        textBlock.Text = "Question";
        textBlock.Name = "Test" + i.ToString();
    
        stack.Children.Add(textBlock);
        beGrid.Children.Add(stack);
        Grid.SetRow(stack, items.Count);
    
        items.Add(stack);
    }
    

    you can access any previos panel by index, e.g. items[0], and get elements from Children property: items[0].Children[0] as TextBlock