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.