简体   繁体   中英

How to set a value to the tag of the cell of a bound DataGridView?

The following class is an example of what I am dealing with:

class Item
{
    public int ID {get;set;}
    public string Name {get;set;}
    public int Quantity {get;set;}
    public string Unit {get;set;}

   public override string ToString()
   {
       return string.Format("{0}({1}){2}{3}", Name,Quantity,Environment.NewLine,Unit);
   }
}

class Items
{
    List<Item> _items;

    public DataTable AllItems()
    {
        var dt = new DataTable();
        // Some manipulation to convert the list to a datatable
        // ...

        return dt;
    }
}

class UI
{
    public void PopulateDatagridview()
    {
        //Some code to create the items
        // ...

        datagridview1.DataSource = items.AllItems();
    }

    private void datagridview1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Control && e.KeyCode == Keys.C)  // Control + c
        {
            // here I need to copy only the item name                
        }
    } 
}

I need to copy only the item name from the grid, the simple and "ugly" solution will be to parse the cell text and then to get the item name. But I will have to update this code each time that my Item.ToString() is updated. One solution I though was to save the item ID in each cell, in that way I could easily retrieve the item name from the items object. I want to save the Item ID to the Tag property of the cell but since I am populating the DataGridView by binding the DataTable to its DataSource, I cannot save it.

Is there a way to save a value to the tag of the cells of a bound DataGridView?

I am afraid your problem is during creation of DataTable. Try using this:

var table = new DataTable("foo");
table.Columns.Add("Column", typeof(Item));

table.Rows.Add(new Item() { Name = "Foo", Quantity = 1, Unit = "kb" });

dataGridView1.DataSource = table;

and then you can work with selection in a typed manner instead of parsing strings:

private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control && e.KeyCode == Keys.C)
    {
        Console.WriteLine("Copying: " + (dataGridView1.SelectedCells[0].Value as Item).Name);
    }
}

You don't need to use "heavy" DataTable . List<Item> can be successfully bound to DataGridView .

Then in KeyDown evenhandler you can access bounded item of currently selected row.

class UI
{
    public void PopulateDatagridview()
    {
        var items = new List<Item> // - create/load items

        datagridview1.DataSource = items;
    }

    private void datagridview1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Control && e.KeyCode == Keys.C)
        {
            var gridView = (DataGridView)sender;
            var item = (Item)gridView.CurrentRow.DataBoundItem;
            var nameForCopy = item.Name;  
            // use nameForCopy ...             
        }
    } 
}

If you big fan of DataTable - you can still using same approach, but only need to cast bounded item to DataRowView and then access value through .Row property.

var gridView = (DataGridView)sender;
var rowView = (DataRowView)gridView.CurrentRow.DataBoundItem;
var nameForCopy = rowView.Row.Field<string>("Name");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM