C# 尝试在DataGridView中为每行动态添加具有唯一标识的按钮

C# 尝试在DataGridView中为每行动态添加具有唯一标识的按钮,c#,button,datagridview,datagridviewcolumn,dynamic-usercontrols,C#,Button,Datagridview,Datagridviewcolumn,Dynamic Usercontrols,我一直在尝试使用此代码执行上述操作: protected void Page_Load(object sender, EventArgs e) { if (!this.IsPostBack) { //Populating a table from the database SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["connect"].T

我一直在尝试使用此代码执行上述操作:

protected void Page_Load(object sender, EventArgs e)
{
    if (!this.IsPostBack)
    {
        //Populating a table from the database
        SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["connect"].ToString());
        con.Open();
        SqlDataAdapter da = new SqlDataAdapter("Select * from tbluser", con);
        DataTable dt = new DataTable();
        da.Fill(dt);
        DataTable finaldt = new DataTable();
        foreach (DataColumn column in dt.Columns)
        {
            if (column.ColumnName == "user_name")
            {
                finaldt.Columns.Add("Username", typeof(string));
            }else if (column.ColumnName == "first_name")
            {
                finaldt.Columns.Add("First Name", typeof(string));
            }else if (column.ColumnName == "last_name")
            {
                finaldt.Columns.Add("Last Name", typeof(string));
            }else if (column.ColumnName == "email")
            {
                finaldt.Columns.Add("E-mail", typeof(string));
            }else if (column.ColumnName == "grade")
            {
                finaldt.Columns.Add("Grade", typeof(string));
            }
        }
        finaldt.Columns.Add("Edit", typeof(Button));
        foreach (DataRow row in dt.Rows)
        {
            Button removalButton = new Button();
            removalButton.Text = "Remove";
            removalButton.ID = "remove_" + row["user_name"];
            removalButton.Click += new EventHandler(remove_student);
            finaldt.Rows.Add(row["user_name"], row["first_name"], row["last_name"], row["email"], row["grade"], removalButton);
        }

        GridView1.DataSource = finaldt;
        GridView1.DataBind();
在我向“finaldt”添加行的底部附近,我不确定这种逻辑是否完全适用于尝试为具有

finaldt.Columns.Add("Edit", typeof(Button));

线路。我应该在这里做些不同的事情吗?

您不能在
数据表中添加按钮。无论何时加载完
数据表
,都必须将该按钮添加到
数据网格视图行

DataGridViewButtonColumn buttonColumn = new DataGridViewButtonColumn();
buttonColumn.Name = "YourColumn";
buttonColumn.Text = "YourText";

if (YourDataGrid.Columns["YourColumn"] == null)
{
    YourDataGrid.Columns.Insert(4, buttonColumn); //here you have to put the columnIndex
}
然后,您必须添加处理程序:

YourDataGrid.CellClick += dataGridViewButton_CellClick;
然后用它做点什么:

private void dataGridViewButton_CellClick(object sender, DataGridViewCellEventArgs e)
{
    //YOUR CODE IN HERE
}

我希望我没有错过什么;然而,我不确定我是否理解你所说的

“…在DataGridView中为每行动态添加具有唯一标识的按钮”

如果网格中有一列按钮,那么唯一能够“唯一”标识单击了哪个按钮的是它所在的行。使用您的示例在单击按钮时“删除”行很简单…但是;这是一个可以在网格中完成的事件…不一定在按钮单击事件中完成…该事件将不可用,因为按钮位于网格中

我建议您只需添加按钮列,然后连接网格
CellClick
事件并检查按钮列是否被单击。如果单击了按钮列,那么我们只需要获取单击按钮的行索引。使用行索引,您将知道要删除哪一行

但是,这看起来很简单,因为您的示例使用
DataTable
作为网格的数据源,所以可能需要额外的步骤。同样的原则也适用于使用另一种“类型”的数据源。在这种情况下,数据源是一个
数据表。

为网格使用数据源意味着数据源本身和网格显示的内容不一定相同。示例:如果通过单击列标题对网格进行排序,网格将对该列进行倾斜排序,并在网格中显示排序。但是,数据源
DataTable
不一定反映这种排序的可能性很高,因此当用户单击删除按钮时,从网格中返回的行索引将反映“网格”行索引,而不一定反映
DataTable
s行索引

一种可能的解决方案是使用grids
DataBoundItem
属性。这将返回一个可以强制转换为
DataRowView
对象的对象。
DataRowView
对象可用作
DataTable
s
IndexOf
属性的参数,以查找
DataTable
s行索引。因此给出了我们需要从
数据表中删除的行索引。如果需要行索引,下面的注释代码将执行此操作。使用
DataTable.Rows.Remove
属性来删除返回的
DataRowView.row
对象,而不是获取行索引。我希望这有帮助

下面是上述内容的一个示例

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) {
  if (e.RowIndex >= 0 && e.ColumnIndex >= 0 && (!dataGridView1.Rows[e.RowIndex].IsNewRow)) { 
    if (dataGridView1.Columns[e.ColumnIndex].Name == "Remove") {
      DataRowView dataRowView = (DataRowView)dataGridView1.Rows[e.RowIndex].DataBoundItem;
      if (dataRowView != null) {
        //int rowIndex = gridTable.Rows.IndexOf(dataRowView.Row);
        //gridTable.Rows.RemoveAt(rowIndex);
        gridTable.Rows.Remove(dataRowView.Row);
      }
    }
  }
}


DataTable gridTable;

public Form1() {
  InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e) {
  gridTable = GetTable();
  dataGridView1.DataSource = gridTable;
  AddButtonColumnToDGV();
  FillTable(gridTable);
}

private void AddButtonColumnToDGV() {
  DataGridViewButtonColumn buttonCol = new DataGridViewButtonColumn {
    Name = "Remove",
    Text = "Remove",
    UseColumnTextForButtonValue = true
  };
  dataGridView1.Columns.Add(buttonCol);
}

private DataTable GetTable() {
  DataTable dt = new DataTable();
  dt.Columns.Add("User Name", typeof(string));
  dt.Columns.Add("First Name", typeof(string));
  dt.Columns.Add("Last Name", typeof(string));
  dt.Columns.Add("Grade", typeof(string));
  return dt;
}

private void FillTable(DataTable dt) {
  for (int i = 0; i < 10; i++) {
    dt.Rows.Add("Name" + i, "FName" + i, "LNameR" + i, "GradeR" + i);
  }
}
private void dataGridView1\u CellClick(对象发送者,DataGridViewCellEventArgs e){
如果(e.RowIndex>=0&&e.ColumnIndex>=0&&(!dataGridView1.Rows[e.RowIndex].IsNewRow)){
如果(dataGridView1.Columns[e.ColumnIndex].Name==“删除”){
DataRowView DataRowView=(DataRowView)dataGridView1.Rows[e.RowIndex].DataBoundItem;
如果(dataRowView!=null){
//int rowIndex=gridTable.Rows.IndexOf(dataRowView.Row);
//gridTable.Rows.RemoveAt(rowIndex);
删除(dataRowView.Row);
}
}
}
}
数据表网格表;
公共表格1(){
初始化组件();
}
私有void Form1\u加载(对象发送方、事件参数e){
gridTable=GetTable();
dataGridView1.DataSource=gridTable;
AddButtonColumnToDGV();
填充表(网格表);
}
私有void addButtonClumnTodGV(){
DataGridViewButtonColumn ButtonColl=新DataGridViewButtonColumn{
Name=“删除”,
Text=“删除”,
UseColumnTextForButtonValue=true
};
dataGridView1.Columns.Add(buttonCol);
}
私有数据表GetTable(){
DataTable dt=新的DataTable();
添加(“用户名”,类型(字符串));
添加(“名字”,类型(字符串));
添加(“姓氏”,typeof(字符串));
添加(“等级”,类型(字符串));
返回dt;
}
专用空白填充表(数据表dt){
对于(int i=0;i<10;i++){
添加(“名称”+i,“FName”+i,“LNameR”+i,“分级器”+i);
}
}

像这样的方法有一个问题,就是没有地方为每个按钮添加唯一的ID。我需要一个唯一的ID,因为每个按钮的作用都是从数据库中删除该行。除非按钮列中的每个按钮都有某种索引,我可以在单击它并将其放入事件处理程序时访问它?您可以添加一个不可见的列,其中包含数据库的ID。。。无论何时单击,您都可以得到该列的值只有一个问题,datagridview和gridview是一样的吗?因为它不允许我在“GridView1”中添加类型为“DataGridViewButtonColumn”的列。
DataGridView
GridView
是两个不同的东西。我不是100%确定,但是我相信在ASP.net web环境中可以使用
GridView
。主要的一点是,在这两种情况下,您都需要将按钮列与数据源分离。您的代码似乎正在尝试将按钮添加到数据源本身……这可能有效,也可能无效,具体取决于您的数据源。但是,将按钮列添加到数据源本身是没有意义的,因为它与数据源无关。此外,如果向数据源添加按钮,如果试图将数据源写回数据库,则可能需要将其删除。在我的示例中,按钮列仅用作网格的一个单独函数…即删除行