如何动态创建和修改新的Grid行元素?

时间:2019-08-27 12:57:17

标签: c# wpf dynamic wpf-grid

我正在启动一个新的WPF应用程序。 我有一个网格,想要动态创建行(例如,按一个按钮),然后在此行内创建TextView / ProgressBar。

我已经搜索了如何以编程方式创建网格行。但是在每种解决方案中,我都无法访问其中的内容,并且变得毫无用处。

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

我无法访问以前创建的元素。

回答后:

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

要获取创建的TextBlock:var text = (TextBlock)FindName("Test"+i.ToString());

2 个答案:

答案 0 :(得分:1)

您可以将所有创建的StackPanel存储在列表中。

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

您可以按索引访问任何previos面板,例如items[0],并从Children属性中获取元素:items[0].Children[0] as TextBlock

答案 1 :(得分:1)

像这样手动创建控件确实不是WPF方式...

最好的方法是定义一个项目类,该项目类包含要显示/编辑的每个值的属性。

然后在窗口中为这些项目创建一个ObservableCollection(因为您将在单击按钮时手动添加项目),并将其设置为ItemsSource控件的ItemsControl属性。 DataTemplate用于定义确切的控件以显示控件中的每个项目,这些控件将绑定到该项目的属性。