如何从 List<> C# 在 DataGridView 中添加按钮?

How to add buttons in a DataGridView from a List<> C#?

如标题所说,我希望能够从 List.

的 DataGridView 中添加按钮

我目前拥有的:

public class Users
{
    public Int64 UserID { get; set; }
    public DataGridViewButtonColumn EmailAddress { get; set; }
    public DataGridViewButtonColumn Gamertag { get; set; }
    public DataGridViewButtonColumn Xuid { get; set; }
    public String SignedIn { get; set; }
    public String AutoSignin { get; set; }
    public Image Gamerpic { get; set; }
}

private List<Users> GetUsersList()
{
    try
    {
        List<Users> list = new List<Users>();
        IEnumerable<XboxUser> users = _xbc.Users;
        foreach (XboxUser user in users)
        {
            DataGridViewButtonColumn EmailAddress = new DataGridViewButtonColumn()
            {
                Text = user.EmailAddress
            };
            DataGridViewButtonColumn Gamertag = new DataGridViewButtonColumn()
            {
                Text = user.GamerTag
            };
            DataGridViewButtonColumn Xuid = new DataGridViewButtonColumn()
            {
                Text = user.Xuid
            };
            Users xbuser = new Users()
            {
                UserID = user.UserId,
                EmailAddress = EmailAddress,
                Gamertag = Gamertag,
                Xuid = Xuid,
                SignedIn = user.IsSignedIn.ToString(),
                AutoSignin = user.AutoSignIn.ToString(),
                Gamerpic = GetImageFromUrl(Gamertag.Text)
            };
            list.Add(xbuser);
        }
        return list;
    }
    catch (Exception ex)
    {
    }
    return null;
}

private void Bo_Refresh_Click(object sender, EventArgs e)
{
    List<Users> listUsers = GetUsersList();
    Dg_UserList.DataSource = new BindingSource(new BindingList<Users>(listUsers), null);
}

private void Dg_UserList_CellClick(object sender, DataGridViewCellEventArgs e)
{
    switch (e.ColumnIndex)
    {
        case 1:
            Clipboard.SetText(Dg_UserList.Rows[e.RowIndex].Cells["EmailAddress"].Value.ToString());
            MessageBox.Show("Email " + Dg_UserList.Rows[e.RowIndex].Cells["EmailAddress"].Value.ToString() + " has been copied in the clipboard.", "Copy to Clipboard", MessageBoxButtons.OK, MessageBoxIcon.Information);
            break;
        case 2:
            Clipboard.SetText(Dg_UserList.Rows[e.RowIndex].Cells["Gamertag"].Value.ToString());
            MessageBox.Show("Gamertag " + Dg_UserList.Rows[e.RowIndex].Cells["Gamertag"].Value.ToString() + " has been copied in the clipboard.", "Copy to Clipboard", MessageBoxButtons.OK, MessageBoxIcon.Information);
            break;
        case 3:
            Clipboard.SetText(Dg_UserList.Rows[e.RowIndex].Cells["Xuid"].Value.ToString());
            MessageBox.Show("Xuid " + Dg_UserList.Rows[e.RowIndex].Cells["Xuid"].Value.ToString() + " has been copied in the clipboard.", "Copy to Clipboard", MessageBoxButtons.OK, MessageBoxIcon.Information);
            break;
    }
}

除按钮外,一切都正确显示(甚至是 Gamerpic 中的图像),按钮显示 DataGridViewButtonColumn { Name=, Index=-1 } 而不是具有正确值的按钮。

我也用 DataGridVewButtonCell 试过,但也不行。

但是,当我点击一个应该是按钮的单元格时,Clipboard.SetText 有效但总是在其中放入 DataGridViewButtonColumn { Name=, Index=-1 }

编辑: 我已经能够使用 Strings 来完成它......看起来不太用户友好,因为没有按钮告诉你可以点击它......但它有效!我当然更喜欢按钮 :)

问题

DataSourced 时,DataGridView 将根据每列的数据类型自动创建列。默认情况下,此处的每一列都创建为 DataGridViewTextBoxColumn,但绑定到 Image 的列除外 - 它将默认为 DataGridViewImageColumn。即使您有三个 DataGridViewButtonColumn 属性,它们也将绑定到文本列 - 这将按如下方式设置值(示例):

NewRow.Cells[1].Value = DataSourceObject.EmailAddress.ToString();

// I.E. EmailAddress is a DataGridViewButtonColumn, so...
NewRow.Cells[1].Value = DataGridViewButtonColumn.ToString();

Console.WriteLine(DataGridViewButtonColumn.ToString()); // prints "DataGridViewButtonColumn { Name=, Index=-1 }"

解决方案

Users class 开始:将所有 DatagridViewButtonColumn 属性更改为类型 string

public class Users
{
    public Int64 UserID { get; set; }
    public String EmailAddress { get; set; }
    public String Gamertag { get; set; }
    public String Xuid { get; set; }
    public String SignedIn { get; set; }
    public String AutoSignin { get; set; }
    public Image Gamerpic { get; set; }
}

并更改您的 GetUserList 方法以解决差异:

private List<Users> GetUsersList()
{
    try
    {
        List<Users> list = new List<Users>();
        IEnumerable<XboxUser> users = _xbc.Users;

        foreach (XboxUser user in users)
        {
            Users xbuser = new Users()
            {
                UserID = user.UserId,
                EmailAddress = user.EmailAddress,
                Gamertag = user.Gamertag,
                Xuid = user.Xuid,
                SignedIn = user.IsSignedIn.ToString(),
                AutoSignin = user.AutoSignIn.ToString(),
                Gamerpic = GetImageFromUrl(Gamertag.Text)
            };

            list.Add(xbuser);
        }

        return list;
    }
    catch (Exception ex)
    {
    }

    return null;
}

最后,在您的 Form 构造函数或 Load 事件中 - 在您绑定数据之前 - 像这样手动添加列:

Dg_UserList.AutoGenerateColumns = false;

DataGridViewTextBoxColumn userCol = new DataGridViewTextBoxColumn();
DataGridViewButtonColumn emailCol = new DataGridViewButtonColumn();
DataGridViewButtonColumn tagCol = new DataGridViewButtonColumn();
DataGridViewButtonColumn xuidCol = new DataGridViewButtonColumn();
DataGridViewTextBoxColumn signCol = new DataGridViewTextBoxColumn();
DataGridViewTextBoxColumn autoCol = new DataGridViewTextBoxColumn();
DataGridViewImageColumn picCol = new DataGridViewImageColumn();

userCol.Name = "UserID";                    // Allows access to columns or
emailCol.Name = "EmailAddress";             // cells in the following manner:
tagCol.Name = "Gamertag";                   // dgv.Rows[index].Cells["Name"];
xuidCol.Name = "Xuid";
signCol.Name = "SignedIn";
autoCol.Name = "AutoSignin";
picCol.Name = "Gamerpic";

userCol.DataPropertyName = "UserID";        // MUST match DataSource properties.
emailCol.DataPropertyName = "EmailAddress"; // Allows DataSourced columns to match
tagCol.DataPropertyName = "Gamertag";       // up with manually created columns.
xuidCol.DataPropertyName = "Xuid";
signCol.DataPropertyName = "SignedIn";
autoCol.DataPropertyName = "AutoSignin";
picCol.DataPropertyName = "Gamerpic";

userCol.HeaderText = "User ID";             // Allows displaying different text
emailCol.HeaderText = "Email Address";      // for the column headers.
tagCol.HeaderText = "Gamer Tag";
xuidCol.HeaderText = "Xuid";
signCol.HeaderText = "Signed In";
autoCol.HeaderText = "Auto Sign in";
picCol.HeaderText = "Avatar";

Dg_UserList.Columns.Add(userCol);
Dg_UserList.Columns.Add(emailCol);
Dg_UserList.Columns.Add(tagCol);
Dg_UserList.Columns.Add(xuidCol);
Dg_UserList.Columns.Add(signCol);
Dg_UserList.Columns.Add(autoCol);
Dg_UserList.Columns.Add(picCol);

这将允许您创建按钮列,但仍然允许您绑定数据而不是手动添加每一行。感谢 DataPropertyName 按钮单元格将正确显示绑定的单元格值。