DirectX表单
DirectXForm为所有驻留在其表面上的控件启用DirectX硬件加速,并支持DirectX渲染模式。
与启用DirectX的控件驻留在常规表单上的标准技术相比,DirectX表单具有以下优点:
- 所有启用DirectX的控件都在单个设备上下文中呈现,当表单承载大量子控件时,这种技术提供了明显更好的性能。
- 启用DirectX的控件消耗更少的内存。
- DirectX表单和他们的子控件可以有任何形状和不透明度,由本地DirectX绘制方法。
- 表单大小调整计算更快,大小调整动画更平滑。
- 专用的HTML和CSS模板允许您创建自定义表单设计。
局限性
支持子控件
DirectX表单无法呈现不支持DirectX的子控件,当前不支持的DevExpress WinForms控件列表:
- 电子表格
不支持的控件列表与DirectX硬件加速文章中的DirectX兼容控件列表不同。例如,SimpleButton、RadioGroup和TokenEdit不是DirectX-ready控件:它们没有启用DirectX渲染的属性,并且在调用全局WindowsFormsSettings.ForceDirectXPaint()方法时不能切换到DirectX模式,然而,当放置在DirectX表单中时,这些控件开始使用DirectX API。
下面的自定义方法允许您识别放置在表单上的控件是否使用DirectX呈现:
C#:
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; }
VB.NET :
Private Function CheckDirectXEnabled(ByVal testedControl As Control) As Boolean If Not testedControl.IsHandleCreated Then Return False End If Dim dxClient = TryCast(testedControl, DevExpress.Utils.DirectXPaint.IDirectXClient) If dxClient Is Nothing Then Dim dxProvider = TryCast(testedControl, DevExpress.Utils.DirectXPaint.IDirectXClientProvider) dxClient = dxProvider?.DirectXClient End If If dxClient Is Nothing Then Return False End If Return dxClient.DirectXProvider.Enabled End Function
我们不断扩展可以在DirectX Forms中托管的控件的数量,并期望在DirectX Form退出CTP阶段时支持整套DevExpress WinForms控件。
多文档接口
DirectX表单不支持MDI布局,因此,不能将现有的MDI表单转换为DirectX表单。
HTML模板
与其他支持HTML和CSS模板的控件类似,DirectX Form实例暴露了HtmlTemplate属性,允许您设计自定义模板,每个DirectX表单都从下默认模板开始:
<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>
这个默认模板的CSS部分是空的,标准元素的外观和行为存储在内部,元素的外观取决于标记(例如,<dx-form-icon>或<dx-form-maximizebutton>),而元素的行为取决于标记ID。例如,下面的标记创建了一个看起来像关闭按钮,但行为像最小化按钮的按钮:
<dx-form-closebutton id="minimizebutton"></dx-form-closebutton>
您可以使用这些标准元素和 IDs 来避免编写额外的代码。下面的标记创建一个具有自定义外观的按钮,由于“closebutton”ID,该按钮充当关闭按钮,则不需要指定自定义方法并将其分配给按钮的onclick属性。
<div id="closebutton" class="button"> <img src="Close" class="button-glyph" /> </div>
提示:标签IDs是唯一的值,不能添加具有相同IDs的多个元素。
“frame”和“content”IDs 为必选项,没有这些IDs 元素的模板被认为是无效的。
- 带有“frame”ID的元素指定了表单的大小调整区域。
- 带有“content”ID的元素指定表单的客户端区域(子控件驻留的区域)。
因此,自定义模板所需的最小标记如下:
HTML:
<div id="frame" class="frame"> <div id="content"> </div> </div>
CSS:
.frame { height: 100%; }
然后可以向这个基本模板添加元素和CSS样式,下面的示例模板可以在DevExpress WinForms演示中心(HTML演示模块)中找到:
HTML:
<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>
点击复制
CSS :
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; } 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; }
点击复制
在上面的示例中,没有使用body样式的HTML元素,它作为一个全局样式,为<frame>元素设置12px填充,这个空白区域允许<frame>元素绘制它的阴影(.frame style的box-shadow属性)。
标题栏中元素的Mouse 事件
位于DirectX表单标题栏中的元素不会引发HtmlElementMouseClick事件,只有标准的最小化、最大化和关闭按钮在单击时触发此事件。
以下来自DirectX Form演示的标记向标题栏添加了五个元素,在这五个元素中,只有Close按钮可以触发HtmlElementMouseClick事件。
<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>
这是因为父标题栏拦截了所有mouse事件,当指针位于标题栏上并且用户按下鼠标按钮时,表单将此操作视为拖放(移动)操作的开始。要使header元素具有交互性(允许它们引发onclick方法并触发HtmlElementMouseClick事件),您需要将它们的HtmlElementMouseDown事件设置为已处理。
例如,下面的代码检查元素ID,如果ID用“button”开头,则为该元素启用Handled属性。
C#:
this.HtmlElementMouseDown += (s, e) => { var args = e.MouseArgs as DXMouseEventArgs; if (e.ElementId.StartsWith("button")) args.Handled = true; };
VB.NET :
AddHandler Me.HtmlElementMouseDown, Sub(s, e) Dim args = TryCast(e.MouseArgs, DXMouseEventArgs) If e.ElementId.StartsWith("button") Then args.Handled = True End If End Sub