DirectXForm Class
The Form that accepts HTML and CSS templates and enables the DirectX rendering for all child controls that support this mode. Unsupported controls are hidden.
Namespace: DevExpress.XtraEditors
Assembly: DevExpress.XtraBars.v24.2.dll
Declaration
[DxHtmlTargetType("DirectX Form", typeof(DirectXFormHtmlServiceProvider))]
public class DirectXForm :
DirectXFormBase,
IDesignTimeToobarHandler,
IScaleDpiProvider,
IToolbarManagerOwner,
ICustomLinksControl,
IAutoOpenMenuBar,
ICustomBarControl,
IBarObject
Remarks
The DirectXForm
enables the DirectX Hardware Acceleration for all controls that reside on its surface and support the DirectX rendering mode.
When compared to the standard technique where DirectX-enabled controls reside on a regular Form, the DirectX Form has the following advantages:
All DirectX-enabled controls are rendered in a single device context. This technique offers a significantly better performance when a Form hosts a large number of child controls.
DirectX-enabled controls consume less memory.
DirectX Forms and their child controls can have any shape and opacity due to native DirectX paint methods.
Form resize calculations are faster, and resize animations are smoother.
A dedicated HTML and CSS template allows you to create custom Form designs.
Limitations
Supported Child Controls
DirectX forms cannot render child controls that do not support DirectX. The list of currently unsupported DevExpress WinForms controls:
The list of unsupported controls differs from the list of DirectX-compatible controls from the DirectX Hardware Acceleration article. For example, SimpleButton, RadioGroup and TokenEdit are not DirectX-ready controls: they do not have properties that enable the DirectX rendering, and do not switch to DirectX mode when you call the global WindowsFormsSettings.ForceDirectXPaint() method. However, when placed inside a DirectX Form, these controls start using DirectX API.
Tip
The following custom method allows you to identify whether a control placed on a Form uses the DirectX rendering:
bool CheckDirectXEnabled(Control testedControl) {
if (!testedControl.IsHandleCreated)
return false;
var dxClient = testedControl as DevExpress.Utils.DirectXPaint.IDirectXClient;
if (dxClient == null) {
var dxProvider = testedControl as DevExpress.Utils.DirectXPaint.IDirectXClientProvider;
dxClient = dxProvider?.DirectXClient;
}
if (dxClient == null)
return false;
return dxClient.DirectXProvider.Enabled;
}
We continuously expand the number of controls that can be hosted inside DirectX Forms, and expect to support the entire set of DevExpress WinForms controls by the time the DirectX Form exits the CTP stage.
Multi-Document Interface
DirectX Forms do not support the MDI layout. As such, you cannot convert existing MDI forms to DirectX Forms.
HTML Template
Similar to other controls that support HTML & CSS templates, DirectX Form instances expose the HtmlTemplate property that allows you to design a custom template. Every DirectX Form starts with the following default template:
<dx-form-frame id="frame">
<dx-form-titlebar id="titlebar">
<dx-form-icon id="icon"></dx-form-icon>
<dx-form-text id="text"></dx-form-text>
<dx-form-minimizebutton id="minimizebutton"></dx-form-minimizebutton>
<dx-form-maximizebutton id="maximizebutton"></dx-form-maximizebutton>
<dx-form-closebutton id="closebutton"></dx-form-closebutton>
</dx-form-titlebar>
<dx-form-content id="content"></dx-form-content>
</dx-form-frame>
The CSS section for this default template is empty, and standard element appearance and behavior are stored internally. Element appearance depends on the tag (for instance, <dx-form-icon>
or <dx-form-maximizebutton>
), whereas element behavior depends on the tag ID. For example, the following markup creates a button that looks like a Close button, but behaves like a Minimize button:
<dx-form-closebutton id="minimizebutton"></dx-form-closebutton>
You can use these standard elements and IDs to avoid writing additional code. The following markup creates a button with a custom appearance. This button acts as a Close button because of the “closebutton” ID. You do not need to specify a custom method and assign it to the button’s onclick
property.
<div id="closebutton" class="button">
<img src="Close" class="button-glyph" />
</div>
Important
Tag IDs are unique values. You cannot add multiple elements with the same IDs.
The “frame” and “content” IDs are mandatory. A template without elements that have these IDs is considered invalid.
An element with the “frame” ID specifies the resize area of a form.
An element with the “content” ID specifies the form’s client area (the area where child controls reside).
As a result, the minimum required markup for a custom template is as follows:
<div id="frame" class="frame">
<div id="content">
</div>
</div>
.frame {
height: 100%;
}
You can then add elements and CSS styles to this basic template. The following sample template can be found in the DevExpress WinForms Demo Center (the HTML demo module):
<div class="root">
<div class="frame" id="frame">
<div class="caption">
<div class="title">DirectX Form</div>
<div id="closebutton" class="button">
<img src="Close" class="button-glyph" />
</div>
</div>
<div class="content" id="content"></div>
</div>
</div>
body {
padding: 12px;
}
.root {
border: 1px solid rgba(0,0,0,0.1);
}
.frame {
height: 100%;
display: flex;
flex-direction: column;
box-shadow: 2px 2px 8px @DisabledText;
}
.caption {
background-color: @Control;
height: 32px;
display: flex;
flex-direction: row;
align-content: center;
padding: 8px 8px 8px 16px;
}
.content {
background-color: @Control;
flex-grow: 1;
}
.button {
width: 32px;
height: 32px;
min-width: 32px;
min-height: 32px;
align-self: center;
border-radius: 4px;
}
.button:hover {
background-color: @DisabledText/0.3;
}
.button:active {
background-color: @DisabledText/0.7;
}
.button-glyph {
width: 16px;
height: 16px;
min-width: 16px;
min-height: 16px;
margin: 8px;
opacity: 0.5;
}
.title {
color: @ControlText;
flex-grow: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
align-self: center;
font-size: 18px;
}
Tip
In the sample above, there is no HTML element that uses the body
style. It acts as a global style and sets the 12px padding for the <frame>
element. This empty area allows the <frame>
element to draw its shadow (the box-shadow
property of the .frame
style).
Custom Fields - Display Dynamic Content
You can also use custom fields in HTML & CSS template:
Add a field name to your template:
${MyField}
Override the form’s
GetHtmlText
method:protected override string GetHtmlText(string fieldName, DxHtmlElementBase element) { if (fieldName == "MyField") return "MyFieldValue"; return base.GetHtmlText(fieldName, element); }
Mouse Events for Elements in the Title Bar
Elements located in the title bar of the DirectX Form do not raise the HtmlElementMouseClick
event. Only standard Minimize, Maximize, and Close buttons trigger this event when clicked.
The following markup from the DirectX Form demo adds five elements to the title bar. Of these five elements, only the Close button can trigger the HtmlElementMouseClick
event.
<div class="shadowframe">
<div class="frame" id="frame">
<div class="titlebar">
<img class="logo" src="Logo" /> <!--No Click event-->
<div class="searchbox"> <!--No Click event-->
<img class="searchimage" src="Search" />
</div>
<div class="addbutton"> <!--No Click event-->
<div class="addbuttoncontainer">
<img class="addimage" src="Add" />
<div class="addbuttontext">Add New</div>
</div>
</div>
<img class="button" src="User" id="loginbutton" /> <!--No Click event-->
<img class="button" src="Close" id="closebutton"/> <!--Raises the Click event-->
</div>
<!--...-->
</div>
</div>
This happens because the parent title bar intercepts all mouse events. When a pointer is over a title bar and a user presses a mouse button, the form considers this action to be the start of a drag-and-drop (move) operation. To make header elements interactive (allow them to raise their onclick
methods and trigger the HtmlElementMouseClick
event), you need to set their HtmlElementMouseDown
events as handled.
For example, the code below checks element IDs, and if an ID starts with “button”, enables the Handled
property for this element.
this.HtmlElementMouseDown += (s, e) => {
var args = e.MouseArgs as DXMouseEventArgs;
if (e.ElementId.StartsWith("button"))
args.Handled = true;
};