简体   繁体   中英

How to render a data-bound WinForms DataGridView Column with an Icon?

In my C# Windows Forms application I have a DataGridView that is bound to a BindingList<Item> list which in turn is initialised with a List<Item> .

// bind view to controller
myDataGridView.DataBindings.Add("DataSource", myController, "Items");

// bind controller to model
Items = new BindingList<Item>(model.Items);

Hence, the columns of the datagrid are generated according to the properties of class Item . I provided a handler method for the DataGridView s CellFormatting event to display certain cell values depending on certain property values of the Item type:

myDataGridView.CellFormatting += new DataGridViewCellFormattingEventHandler(myontroller.HandleCellFormatting);

I now also want to add one of two possible icons to every row in the grid, also depending on the value of certain properties of Item . Note that there is now direct correspondance to any of Items' properties, so I cannot have an extra column in my grid to hold the icon. So guess I have to either add an icon to an already existing cell or maybe generate an appropriate column on the fly. Any ideas ?

You need to handle CellPainting event of DataGridView and paint the cell yourself.

Example

This example shows how you can draw an image in a bound-column of DataGridView so the column shows bound data, as well as image. For example, here I decided to draw a red icon for negative numbers, a silver icon for zero numbers and a green icon for positive numbers:

在此处输入图片说明

To do so, define some variables to keep reference to the images. We will use this variables to render images and also to dispose the image when we no more need it:

Image zero, negative, positive;

Handle Load event of the form and images from file, resource or wherever you have stored images and assign to those variables. Set up data binding. Set up a suitable left padding for the cell in which you are going to paint the icon:

private void Form1_Load(object sender, EventArgs e)
{
    var list = new[] {
        new { C1 = "A", C2 = -2 },
        new { C1 = "B", C2 = -1 },
        new { C1 = "C", C2 = 0 },
        new { C1 = "D", C2 = 1 },
        new { C1 = "E", C2 = 2 },
    }.ToList();
    dataGridView1.DataSource = list;

    zero = new Bitmap(16, 16);
    using (var g = Graphics.FromImage(zero))
        g.Clear(Color.Silver);
    negative = new Bitmap(16, 16);
    using (var g = Graphics.FromImage(negative))
        g.Clear(Color.Red);
    positive = new Bitmap(16, 16);
    using (var g = Graphics.FromImage(positive))
        g.Clear(Color.Green);

    //Set padding to have enough room to draw image
    dataGridView1.Columns[1].DefaultCellStyle.Padding = new Padding(18, 0, 0, 0);
}

Handle CellPainting event of the DataGridView and render the cell contents and the image for the columns which you want:

private void DataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    //We don't need custom paint for row header or column header
    if (e.RowIndex < 0 || e.ColumnIndex != 1) return;

    //We don't need custom paint for null value
    if (e.Value == null || e.Value == DBNull.Value) return;

    //Choose image based on value
    Image img = zero;
    if ((int)e.Value < 0) img = negative;
    else if ((int)e.Value > 0) img = positive;

    //Paint cell
    e.Paint(e.ClipBounds, DataGridViewPaintParts.All);
    e.Graphics.DrawImage(img, e.CellBounds.Left + 1, e.CellBounds.Top + 1,
        16, e.CellBounds.Height - 3);

    //Prevent default paint
    e.Handled = true;
}

Handle FormClosing event to dispose the images:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    //Dispose images
    if (zero != null) zero.Dispose();
    if (negative != null) negative.Dispose();
    if (positive != null) positive.Dispose();
}

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