You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF技术问题:如何通过行内按钮删除Grid中的行?

WPF Grid点击按钮删除对应行的实现方案

问题分析

你当前的实现有两个核心问题:

  • 全局currentRow变量会被每次新增的行覆盖,导致点击删除按钮时无法定位到按钮所在的目标行
  • 删除按钮未绑定点击事件,且没有建立按钮与所在行的关联逻辑

解决代码与步骤

1. 修改行添加逻辑,绑定删除按钮事件

更新ItemAdd方法,给每个删除按钮绑定点击事件,并简化序号赋值逻辑:

private void ItemAdd(object sender, RoutedEventArgs e)
{
    Button deleteButton = new Button { Visibility = Visibility.Visible, Content = "X" };
    // 绑定删除按钮点击事件
    deleteButton.Click += DeleteButton_Click;

    TextBox itemName = new TextBox { MinHeight = 10, MaxHeight = 40 };
    TextBox weight = new();
    Label number = new Label();

    RowDefinition row = new()
    { Height = GridLength.Auto, MinHeight = 10 };
    NamesList.RowDefinitions.Add(row);

    // 直接用当前行的索引作为序号(新增行的索引是RowDefinitions.Count-1)
    int rowIndex = NamesList.RowDefinitions.Count - 1;
    number.Content = rowIndex;

    AddAt(NamesList, number, rowIndex, 0);
    AddAt(NamesList, itemName, rowIndex, 1);
    AddAt(NamesList, weight, rowIndex, 2);
    AddAt(NamesList, deleteButton, rowIndex, 3);
}

2. 实现删除按钮点击事件

通过按钮获取所在行的索引,先移除该行内所有控件,再删除行定义,最后更新剩余行的序号:

private void DeleteButton_Click(object sender, RoutedEventArgs e)
{
    Button deleteBtn = sender as Button;
    if (deleteBtn == null) return;

    // 获取按钮所在的行索引
    int targetRowIndex = Grid.GetRow(deleteBtn);
    var grid = NamesList;

    // 移除该行内的所有控件(避免控件残留)
    RemoveControlsInRow(grid, targetRowIndex);

    // 删除目标行定义
    grid.RowDefinitions.RemoveAt(targetRowIndex);

    // 更新剩余行的序号标签
    RefreshRowNumbers(grid);
}

// 移除指定行内的所有控件
private void RemoveControlsInRow(Grid grid, int rowIndex)
{
    var controlsToRemove = grid.Children.Cast<UIElement>()
        .Where(elem => Grid.GetRow(elem) == rowIndex)
        .ToList();

    foreach (var control in controlsToRemove)
    {
        grid.Children.Remove(control);
    }
}

// 更新所有行的序号标签
private void RefreshRowNumbers(Grid grid)
{
    for (int i = 0; i < grid.RowDefinitions.Count; i++)
    {
        // 找到每行第0列的序号Label
        var numberLabel = grid.Children.Cast<UIElement>()
            .FirstOrDefault(elem => Grid.GetRow(elem) == i && Grid.GetColumn(elem) == 0) as Label;

        if (numberLabel != null)
        {
            numberLabel.Content = i;
        }
    }
}

关键说明

  • 不再依赖全局currentRow变量,而是通过Grid.GetRow(deleteBtn)直接获取按钮所在行的索引,确保删除的是目标行
  • 删除行前必须先移除该行内的所有控件,否则这些控件会继续留在Grid中并显示到其他行
  • 删除行后更新序号标签,保证序号与行的实际位置一致

内容的提问来源于stack exchange,提问作者infi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:35:05