In this post, I'll outline important Do's and Don'ts when using the DevExpress WinForms HTML/CSS engine/templates. If you are new to DevExpress/considering our WinForms UI Library for an upcoming project and have yet to explore the potential of our WinForms HTML/CSS feature, please take a moment to review the following online content first:
HTML & CSS Markup for WinForms UI | DevExpress
Do's when Using HTML/CSS
The following WinForms usage scenarios require basic HTML/CSS knowledge.
Customize UI Elements of HTML-CSS-aware Controls (Simple)
Use HTML/CSS Templates to create custom UI elements for DevExpress HTML/CSS-aware controls (and eliminate manual painting within CustomDraw~
event handlers). With our WinForms HTML/CSS engine, you can customize ListBox and Combobox items, Cards within our TileView/ItemsView/WinExplorerView, Scheduler appointments, message boxes, tooltips, etc. You can retrieve values from data fields for data-aware controls, implement bindings based on a condition, and use DevExpress skin colors.
For example, our WinForms Accordion control includes multiple HTML templates for various UI elements (such as item, footer, group, header panel, menu, buttons, separator, etc.):

Our Visual Studio-integrated HTML/CSS Template Editor allows you to manage appearance customizations on the design surface. The HTML/CSS Template Editor uses an embedded Syntax Editor with IntelliSense, autocomplete, tag navigation, and preview (to simplify/facilitate use of HTML templates within any DevExpress-powered WinForms project).

Our HTML/CSS Template Editor includes a set of predesigned/reusable templates. You can use these templates "as-is" or extend as needs dictate. You can also create a custom HTML & CSS template, save the template to the gallery, and use it in any WinForms project when desired.
Customize Control UI Elements Using CustomDraw~ Events (Simple)
Not all DevExpress WinForms control UI elements that can be custom painted via CustomDraw~ events support HTML/CSS templates. However, event arguments of all CustomDraw~ events include a DrawHtml()
method. This method draws an HTML/CSS template on top of a UI element.
The following example draws a badge on top of "Page B":

using DevExpress.XtraTab;
void xtraTabControl_CustomDrawTabHeader(object sender, TabHeaderCustomDrawEventArgs e) {
if (e.TabHeaderInfo.Page == tabPageB) {
e.DefaultDraw();
e.Handled = true;
e.DrawHtml(htmlTemplateBadge);
}
}
Custom Draw~/DrawHTML() Implementation Details (Video)
Common usage scenarios for this capability include:
- Customize preview rows within the WinForms Data Grid control (Run Demo).
- Customize TreeList node preview sections (Run Demo).
- Display custom content within an empty control (Run Demo).
- Customize card captions within the Layout Control.
Customize Layout and Implement Data Editing within Grid Views (Simple)
We designed our Grid's TileView
, ItemsView
, and ExplorerView
to present data in an organized and visually elegant manner. However, data editing within these views has traditionally required use of additional UI elements (these Grid Views do not support data editing out of the box).
To address this limitation, you can embed DevExpress Data Editors within HTML/CSS item templates. The following animation demonstrates use of WinForms Grid TileView with an embedded RatingControl:

Documentation: Integrate In-place Editors into HTML Templates
Customize Standalone Data Editors (Simple)
Use HTML & CSS templates to customize standalone WinForms Data Editors. Simply drop the appropriate Data Editor on our HtmlContentControl, hide the editor’s border, and customize the HtmlContentControl’s HTML template as needed.

<div class="input-box">
<input class="input" name="emailEdit" value="${Email}"/>
</div>
<div class="input-box">
<input class="input" name="passEdit" value="${Password}"/>
</div>
<div class="check-container">
<input class="check-box" name="checkEdit" value="${RememberMe}"/>
Remember me
</div>
Display Simple Interactive Elements (Simple)
Along with static content, you can also include interactive elements within HTML/CSS templates. HTML-aware controls expose mouse-related events (such as ElementMouseClick
, ElementMouseOver
, ElementMouseDown
, etc.) that you can handle to respond to mouse actions on HTML UI elements.

htmlContentControl.ElementMouseClick += (s, e) => {
if(e.ElementId == "btnPhone")
XtraMessageBox.Show("Phone!");
if(e.ElementId == "btnVideo")
XtraMessageBox.Show("Video!");
if(e.ElementId == "btnText")
XtraMessageBox.Show("Text Message!");
};
<!--HTML Template-->
<div class='buttonPanel'>
<img id="btnPhone" src="PhoneCall" class="button" />
<img id="btnVideo" src="VideoCall" class="button" />
<img id="btnText" src="Message" class="button" />
</div>
Advanced Scenarios
Create Complex Data Entry Forms (Advanced)
HTML/CSS templates allow you to create fully custom data forms. We only recommend use of HTML/CSS templates if our WinForms LayoutControl does not allow you to achieve the desired result. Building layouts from scratch using HTML/CSS can be time-consuming, especially for complex forms with multiple fields. Needless to say, our LayoutControl is built with accessibility in mind. This includes features such as proper labeling, keyboard navigation support, and compatibility with screen readers.

Display Interactive Elements Using CustomDraw~ (Advanced)
Not all DevExpress WinForms UI controls support mouse events (for performance reasons). This limitation does not prevent interactive UI elements from being displayed within DevExpress controls. Nonetheless, it does require more complex code to be written:
DxHtmlPainterContext ctx = new DxHtmlPainterContext();
HtmlTemplate htmlTemplate = new HtmlTemplate(
Loader.Load("ListBoxEmptyForeground.html"),
Loader.Load("ListBoxEmptyForeground.css"));
listControl.CustomDrawEmptyForeground += (s, e) => {
e.DrawHtml(htmlTemplate, ctx);
};
// Handles UI feedback (hover/cursor).
listControl.MouseMove += (s, e) => {
if(listControl.ItemCount == 0) {
ctx.OnMouseMove(e);
listControl.Cursor = ctx.GetCursor(e.Location);
listControl.Invalidate();
}
else listControl.Cursor = Cursors.Default;
};
// Handles Click within the btnAdd element.
var items = Enumerable.Range(1, 10)
.Select(n => string.Format("Item #{0:d2}", n))
.ToArray();
listControl.MouseDown += (s, e) => {
if(listControl.ItemCount == 0 && e.Button == MouseButtons.Left) {
var clickInfo = ctx.CalcHitInfo(e.Location);
if(clickInfo != null && clickInfo.HasId("btnAdd"))
listControl.Items.AddRange(items);
}
};

Documentation: Custom Draw Interactive HTML Templates
Display UI Elements and Bind Associated States to Data Using CustomDraw~ (Advanced)
Unlike static templates, data-aware template rendering requires writing more code (especially if you need to retrieve data from a different source). The following example draws sale badges within Grid cells. Discount size is obtained from a different data source.

using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Base;
using System.Collections.Generic;
namespace DXApplication {
public partial class Form1 : XtraForm {
Dictionary<string, double> discounts = new Dictionary<string, double>() {
{ "A", 0.3 },
{ "B", 0.45 },
{ "C", 0.2 }
};
public Form1() {
InitializeComponent();
gridControl1.DataSource = new List<Product>() {
new Product(){ Category = "A", Name = "AA", Price = 159.99},
new Product(){ Category = "A", Name = "AB", Price = 159.99},
new Product(){ Category = "B", Name = "BA", Price = 49.99},
new Product(){ Category = "B", Name = "BB", Price = 89.99},
new Product(){ Category = "C", Name = "CA", Price = 799.99},
};
gridView1.CustomDrawCell += GridView1_CustomDrawCell;
}
void GridView1_CustomDrawCell(object sender, RowCellCustomDrawEventArgs e) {
e.DefaultDraw();
e.Handled = true;
GridView view = sender as GridView;
string category = view.GetRowCellValue(e.RowHandle, view.Columns["Category"]) as string;
if (e.Column.FieldName == "Price" && discounts.ContainsKey(category)){
e.DrawHtml(htmlTemplateSaleBadge, args => {
args.SetFieldValue("Discount", discounts[category].ToString("p0"));
});
}
}
}
public class Product {
public string Name { get; set; }
public string Category { get; set; }
public double Price { get; set; }
}
}
Documentation: Draw a Data-Aware Template
Create Fully Custom UI Controls using HTML/CSS (Advanced)
Our WinForms HtmlContentControl
is the "surface" upon which to build your WinForms UI using HTML-CSS markup. The WinForms HtmlContentPopup
is its popup version. These components generate a WinForms interface from HTML/CSS code and allow you to design bespoke WinForms UI controls. Creating custom UI controls with DevExpress components and HTML/CSS is an advanced technique that requires in-depth knowledge of both technologies/nuances of UI development.

Visualize Collections (Advanced)
Data sources may include data fields that store items collections: a List, an array, a data set, etc. The <dx-collection>
tag is a unique DevExpress element. It allows you to specify a collection property for items that require visualization (and the template that must be applied to these items). Utilizing custom tags like <dx-collection>
imposes specific requirements on an HTML template for proper functionality.

Don’ts when Using our WinForms HTML & CSS Engine
Don’t create complex nested flex layouts.
(for example, 3 or more nested flex panels)
Don’t create CSS animations.
Don’t modify HTML elements when handling UI control events.
Don’t implement logic in HTML templates based on HTML elements.
It is better to create a separate property in the model and calculate logic in the model.
Do not use pre-written HTML/CSS code from external resources as-is.
Such code may not work, as we do not support all HTML tags/attributes.