Custom Draw Scenarios

  • 5 minutes to read

Custom draw events provide complete control over the appearance of the control's elements. This document covers the main scenarios for custom draw event usage.

NOTE

Custom draw events do not allow you to change the appearance of a printed/exported version of the Tree List.

The TreeList's custom draw events can be handled to implement the following scenarios.

  • Manual Element Rendering

    Custom draw events allow you to manually render Tree List elements using the methods provided by the event's CustomDrawEventArgs.Graphics and CustomDrawEventArgs.Appearance objects. These objects' methods allow you to draw various graphics primitives (lines, rectangles, ellipses, images, etc.).

    When performing manual element rendering, you typically need to set the event's CustomDrawEventArgs.Handled parameter to true. Otherwise, the default painting mechanism will be invoked after event execution, and it will override your rendering.

  • Combining Default Painting and Custom Painting

    This approach allows you to paint custom information over the default rendering. To accomplish this task, first invoke the default painting mechanism for an element using the CustomDrawEventArgs.DefaultDraw method. Then, you can paint additional information over the default rendering using the methods of the event's CustomDrawEventArgs.Graphics and CustomDrawEventArgs.Appearance properties.

    Before invoking the default painting mechanism, you can modify an element's display information (content, bounds and appearance settings) via the event's parameters. The default rendering mechanism, when invoked, will apply these changes.

    A call to the CustomDrawEventArgs.DefaultDraw method automatically sets the event's Handled parameter to true. This prevents the default painting mechanism from being re-invoked after event execution.

    Note that modifying the boundaries of elements or inner elements changes the Tree List layout. If you need to change the boundaries of elements for the purpose of custom painting, you should restore the boundaries immediately after the default painting mechanism is invoked.

  • Customizing Element Display Information for Default Rendering

    When handling a custom draw event, you can change an element's view information (e.g., appearance or content) and set the event's CustomDrawEventArgs.Handled property to false (the default value). In this case, the default rendering will automatically be invoked after event execution. The painting mechanism will use the modified view information to render the element.

NOTE

In specific paint themes (e.g., skins and Office2003), you are not able to change the background of some elements. Changing the background of these elements via the Appearance parameter of custom draw events is also not supported.

Example

The following example custom paints column headers, summary footer, footer cells and indicator cells via the TreeList.CustomDrawColumnHeader, TreeList.CustomDrawFooter, TreeList.CustomDrawFooterCell and TreeList.CustomDrawNodeIndicator events.

Three functions are declared that implement custom painting. These are used to draw the background of the raised and sunken elements, and to paint the text with the predefined alignment within elements.

The image below shows the result.

CustomDraw - TBH1

using System.Drawing.Drawing2D;
using DevExpress.XtraTreeList;
//...

// Custom paints the column headers.
private void treeList1_CustomDrawColumnHeader(object sender, DevExpress.XtraTreeList.CustomDrawColumnHeaderEventArgs e) {
    if (e.Pressed)
        paintSunkenBackground(e);
    else
        paintRaisedBackground(e);
    if (e.ColumnType == HitInfoType.Column)
        paintHAlignedText(e, e.Column.GetCaption(), StringAlignment.Near);
    e.Handled = true;
}

// Custom paints the summary footer.
private void treeList1_CustomDrawFooter(object sender, DevExpress.XtraTreeList.CustomDrawEventArgs e) {
    paintRaisedBackground(e);
    e.Handled = true;
}

// Custom paints the cells of the summary footer.
private void treeList1_CustomDrawFooterCell(object sender, DevExpress.XtraTreeList.CustomDrawFooterCellEventArgs e) {
    if (e.Text == String.Empty) return;
    paintSunkenBackground(e);
    paintHAlignedText(e, e.Text, StringAlignment.Far);
    e.Handled = true;
}

// Custom paints the indicator cells.
private void treeList1_CustomDrawNodeIndicator(object sender, DevExpress.XtraTreeList.CustomDrawNodeIndicatorEventArgs e) {
    paintRaisedBackground(e);
    e.Handled = true;
}

// Custom draw methods:

// Paints the background of raised elements.
private void paintRaisedBackground(CustomDrawEventArgs e)
{
    Brush brush = e.Cache.GetGradientBrush(e.Bounds, Color.Yellow, Color.Gold, LinearGradientMode.Vertical);
    e.Cache.FillRectangle(brush, e.Bounds);
    e.Cache.DrawRectangle(e.Cache.GetPen(Color.LightGray), e.Bounds);
}

// Paints the background of sunken elements.
private void paintSunkenBackground(CustomDrawEventArgs e)
{
    Brush brush = e.Cache.GetGradientBrush(e.Bounds, Color.CornflowerBlue, Color.LightGray, LinearGradientMode.Vertical);
    e.Cache.FillRectangle(brush, e.Bounds);
    e.Cache.DrawRectangle(e.Cache.GetPen(Color.LightGray), e.Bounds);
}

// Paints the aligned text.
private void paintHAlignedText(CustomDrawEventArgs e, String text, StringAlignment align)
{
    Brush textBrush = e.Cache.GetSolidBrush(Color.Black);

    StringFormat outStringFormat = e.Appearance.GetStringFormat();
    outStringFormat.Alignment = align;
    outStringFormat.LineAlignment = StringAlignment.Center;
    outStringFormat.FormatFlags = StringFormatFlags.NoWrap;
    outStringFormat.Trimming = StringTrimming.EllipsisCharacter;

    e.Cache.DrawString(text, e.Appearance.Font, textBrush, e.Bounds, outStringFormat);
}
See Also