windowsforms-114616-controls-and-libraries-data-grid-getting-started-walkthroughs-appearance-and-conditional-formatting-tutorial-custom-drawing.md
This walkthrough is a transcript of the Custom Drawing video available on the DevExpress YouTube Channel.
In this tutorial, you will learn how to use the grid View’s CustomDraw… events. You’ll start with a grid displaying plain task data. First, you’ll use an event to customize the appearance of individual cells. Then, the same event handler will be modified to alter the displayed text in individual cells depending on grid data. You’ll then extend the handler even further to draw images within specific cells. Finally, you’ll see how to custom paint column headers while keeping their interactive elements, such as filter dropdown buttons and sort glyphs.
Start with an application that has a GridControl displaying task data.
Choose the grid View and handle the GridView.CustomDrawCell event. This event provides you with the RowCellCustomDrawEventArgs.RowHandle and RowCellCustomDrawEventArgs.Column parameters that identify the cell being painted.
Customizing Cell Appearance
Changing Cell Display Text
Displaying Custom Images within Cells
To custom paint column headers, subscribe to the GridView.CustomDrawColumnHeader event. Use the gradient from ‘Salmon’ to ‘White’ to fill the background of column headers, and after that, display header captions. Set the event’s CustomDrawEventArgs.Handled parameter to true to prevent the default painting mechanism from being invoked when the event handler is completed.
private void gridView_CustomDrawColumnHeader(object sender, ColumnHeaderCustomDrawEventArgs e) {
Rectangle rect = e.Bounds;
// Create a new brush
using (Brush brush = new LinearGradientBrush(e.Bounds, Color.Salmon, Color.White, LinearGradientMode.ForwardDiagonal)) {
// Fill a column's background
e.Cache.FillRectangle(brush, rect);
// Draw the column's caption
e.Appearance.DrawString(e.Cache, e.Info.Caption, e.Info.CaptionRect);
e.Handled = true;
}
}
Now run the application. Column headers are painted with the ‘Salmon’ to ‘White’ gradient.
However, the usual sort and filter glyphs are not displayed. There is a way to fix this and display standard interactive elements within column headers. You need to enumerate the ColumnHeaderCustomDrawEventArgs.Info .InnerElements collection and use a specially designed method to paint them if their settings indicate that they are currently visible.
private void gridView_CustomDrawColumnHeader(object sender, ColumnHeaderCustomDrawEventArgs e) {
// ...
// Draw the filter and sort buttons.
foreach (DevExpress.Utils.Drawing.DrawElementInfo info in e.Info.InnerElements) {
if (!info.Visible) continue;
DevExpress.Utils.Drawing.ObjectPainter.DrawObject(e.Cache, info.ElementPainter, info.ElementInfo);
}
}
Run the application again to see the result. Now, the headers have a custom appearance while keeping the standard elements so end-users can still interact with column headers in the usual manner.
private void gridView_CustomDrawCell(object sender, DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventArgs e) {
GridView view = sender as GridView;
if (e.RowHandle == view.FocusedRowHandle) return;
if (e.Column.FieldName != "UnitPrice") return;
// Fill a cell's background if its value is greater than 30.
if (Convert.ToInt32(e.CellValue) > 30)
e.Appearance.BackColor = Color.FromArgb(60, Color.Salmon);
// Specify the cell's display text.
double discount = Convert.ToDouble(view.GetRowCellValue(e.RowHandle, view.Columns["Discount"]));
if (discount > 0) {
double unitPrice = Convert.ToDouble(view.GetRowCellValue(e.RowHandle, view.Columns["UnitPrice"]));
double discountPrice = unitPrice * (1 - discount);
e.DisplayText = "Discount price: " + discountPrice.ToString("c2");
}
e.DefaultDraw();
// Paint images in cells if discounts > 0.
Image image = Image.FromFile("c:\\important.png");
if (discount > 0)
e.Cache.DrawImage(image, e.Bounds.Location);
}
private void gridView_CustomDrawColumnHeader(object sender, ColumnHeaderCustomDrawEventArgs e) {
Rectangle rect = e.Bounds;
// Create a new brush
using (Brush brush = new LinearGradientBrush(e.Bounds, Color.Salmon, Color.White, LinearGradientMode.ForwardDiagonal)) {
// Fill a column's background
e.Cache.FillRectangle(brush, rect);
// Draw the column's caption
e.Appearance.DrawString(e.Cache, e.Info.Caption, e.Info.CaptionRect);
e.Handled = true;
}
// Draw the filter and sort buttons.
foreach (DevExpress.Utils.Drawing.DrawElementInfo info in e.Info.InnerElements) {
if (!info.Visible) continue;
DevExpress.Utils.Drawing.ObjectPainter.DrawObject(e.Cache, info.ElementPainter, info.ElementInfo);
}
}
See Also
Elements that Can Be Custom Painted
Appearance and Conditional Formatting
Tutorial: View and Column Appearance
Tutorial: Custom Drawing