商信互联
此示例演示如何自定义控件以可视化UI中的操作。将创建一个自定义动作,允许用户输入日期并相应地过滤列表视图。实施的操作将接受键盘输入,并提供一个下拉日历。代表操作的控件将被自定义为使用自定义掩码接受键盘输入。下图显示了用户界面中的最终操作。
您可以在XAF随附的功能中心应用程序的“操作”部分中看到以下控制器的演示(用于ASP.NET的CustomizeMenuActionsController和用于WinForms的CustomizeParametrizedActionController)。默认情况下,Feature Center演示安装在%PUBLIC%\ Documents \ DevExpress演示19.2 \ Components \ eXpressApp Framework \ FeatureCenter中。该演示的ASP.NET版本可从http://demos.devexpress.com/XAF/FeatureCenter/在线获得。
首先,定义示例MyDomainObject业务类。该类包含两个属性。第一个是DateTime类型的“ CreatedOn”属性,第二个是字符串类型的“ Title”属性。
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Xpo;
// ...
[DefaultClassOptions]
public class MyDomainObject : BaseObject {
public MyDomainObject(Session session) : base(session) { }
public DateTime CreatedOn {
get { return GetPropertyValue<DateTime>(nameof(CreatedOn)); }
set { SetPropertyValue(nameof(CreatedOn), value); }
}
public string Title {
get { return GetPropertyValue<string>(nameof(Title)); }
set { SetPropertyValue(nameof(Title), value); }
}
}
Imports DevExpress.Persistent.Base
Imports DevExpress.Persistent.BaseImpl
Imports DevExpress.Xpo
' ...
<DefaultClassOptions()> _
Public Class MyDomainObject
Inherits BaseObject
Public Sub New(ByVal session As Session)
MyBase.New(session)
End Sub
Public Property CreatedOn() As DateTime
Get
Return GetPropertyValue(Of DateTime)(NameOf(CreatedOn))
End Get
Set(ByVal value As DateTime)
SetPropertyValue(NameOf(CreatedOn), value)
End Set
End Property
Public Property Title() As String
Get
Return GetPropertyValue(Of String)(NameOf(Title))
End Get
Set(ByVal value As String)
SetPropertyValue(NameOf(Title), value)
End Set
End Property
End Class
接下来,创建一个新的View Controller并定义一个ParametrizedAction。配置控制器和操作,以便仅针对MyDomainObject类激活它们。将Action的ParametrizedAction.ValueType设置为DateTime。在Action的ParametrizedAction.Execute事件处理程序中,检查是否输入了日期。如果输入了日期,则过滤MyDomainObject列表视图以仅包含其“ CreatedOn”属性值等于输入日期的对象。如果用户使用空的编辑字段执行了操作,则删除应用的过滤器,以使列表视图显示所有对象,而与它们的创建日期无关。
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.Persistent.Base;
//...
public class MyFilterController : ViewController {
public ParametrizedAction dateFilterAction;
public MyFilterController() {
TargetViewType = ViewType.ListView;
TargetObjectType = typeof(MyDomainObject);
dateFilterAction = new ParametrizedAction(this, "MyDateFilter", PredefinedCategory.Search, typeof(DateTime));
dateFilterAction.NullValuePrompt = "Enter date";
dateFilterAction.Execute = dateFilterAction_Execute;
}
private void dateFilterAction_Execute(object sender, ParametrizedActionExecuteEventArgs e) {
CriteriaOperator criterion = null;
if(e.ParameterCurrentValue != null && e.ParameterCurrentValue.ToString() != string.Empty) {
criterion = new BinaryOperator("CreatedOn", Convert.ToDateTime(e.ParameterCurrentValue));
}
((ListView)View).CollectionSource.Criteria[dateFilterAction.Id] = criterion;
}
}
Imports DevExpress.Data.Filtering
Imports DevExpress.ExpressApp
Imports DevExpress.ExpressApp.Actions
Imports DevExpress.Persistent.Base
'...
Public Class MyFilterController
Inherits ViewController
Public dateFilterAction As ParametrizedAction
Public Sub New()
TargetViewType = ViewType.ListView
TargetObjectType = GetType(MyDomainObject)
dateFilterAction = New ParametrizedAction(Me, "MyDateFilter",
PredefinedCategory.Search, GetType(Date))
dateFilterAction.NullValuePrompt = "Enter date"
AddHandler dateFilterAction.Execute, AddressOf dateFilterAction_Execute
End Sub
Private Sub dateFilterAction_Execute(ByVal sender As Object,
ByVal e As ParametrizedActionExecuteEventArgs)
Dim criterion As CriteriaOperator = Nothing
If e.ParameterCurrentValue IsNot Nothing AndAlso
e.ParameterCurrentValue.ToString() <> String.Empty Then
criterion = New BinaryOperator("CreatedOn", Convert.ToDateTime(e.ParameterCurrentValue))
End If
CType(View, ListView).CollectionSource.Criteria(dateFilterAction.Id) = criterion
End Sub
End Class
要设置自定义编辑蒙版,请订阅ActionBase.CustomizeControl事件。此事件使您可以自定义创建的项目控件,并提供对相应动作控件的访问。
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.XtraBars;
using DevExpress.XtraEditors.Repository;
//...
public class CustomizeActionControlControllerWin : Controller {
protected override void OnActivated() {
base.OnActivated();
Frame.GetController<MyFilterController>().dateFilterAction.CustomizeControl = CustomizeActionControlControllerWin_CustomizeControl;
}
private void CustomizeActionControlControllerWin_CustomizeControl(object sender,
CustomizeControlEventArgs e) {
BarEditItem barItem = e.Control as BarEditItem;
if (barItem != null) {
RepositoryItemDateEdit repositoryItem = (RepositoryItemDateEdit)barItem.Edit;
repositoryItem.Mask.UseMaskAsDisplayFormat = true;
repositoryItem.Mask.EditMask = "yyyy-MMM-dd";
barItem.Width = 270;
}
}
protected override void OnDeactivated() {
Frame.GetController<MyFilterController>().dateFilterAction.CustomizeControl -=
CustomizeActionControlControllerWin_CustomizeControl;
base.OnDeactivated();
}
}
Imports DevExpress.ExpressApp
Imports DevExpress.ExpressApp.Actions
Imports DevExpress.XtraBars
Imports DevExpress.XtraEditors.Repository
'...
Public Class CustomizeActionControlControllerWin
Inherits Controller
Protected Overrides Sub OnActivated()
MyBase.OnActivated()
AddHandler Frame.GetController(Of MyFilterController)().dateFilterAction.CustomizeControl,
AddressOf CustomizeActionControlControllerWin_CustomizeControl
End Sub
Private Sub CustomizeActionControlControllerWin_CustomizeControl(ByVal sender As Object,
ByVal e As CustomizeControlEventArgs)
Dim barItem As BarEditItem = TryCast(e.Control, BarEditItem)
If barItem IsNot Nothing Then
Dim repositoryItem As RepositoryItemDateEdit = CType(barItem.Edit, RepositoryItemDateEdit)
repositoryItem.Mask.UseMaskAsDisplayFormat = True
repositoryItem.Mask.EditMask = "yyyy-MMM-dd"
barItem.Width = 270
End If
End Sub
Protected Overrides Sub OnDeactivated()
RemoveHandler Frame.GetController(Of MyFilterController)().dateFilterAction.CustomizeControl,
AddressOf CustomizeActionControlControllerWin_CustomizeControl
MyBase.OnDeactivated()
End Sub
End Class
此方法使用服务器属性。当您需要更改控件的行为时,请采用这种方法。如果您需要更改控件的外观,请按照“动作自定义”一文中所述使用CSS样式。
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.ExpressApp.Web.Templates.ActionContainers.Menu;
using DevExpress.Web;
//...
public class CustomizeActionControlControllerWeb : Controller {
protected override void OnActivated() {
base.OnActivated();
Frame.GetController<MyFilterController>().dateFilterAction.CustomizeControl = CustomizeActionControlControllerWeb_CustomizeControl;
}
private void CustomizeActionControlControllerWeb_CustomizeControl(object sender,
CustomizeControlEventArgs e) {
ParametrizedActionMenuActionItem actionItem = e.Control as ParametrizedActionMenuActionItem;
if (actionItem != null) {
ASPxDateEdit editor = actionItem.Control.Editor as ASPxDateEdit;
if (editor != null) {
editor.UseMaskBehavior = true;
editor.EditFormat = EditFormat.DateTime;
editor.EditFormatString = "yyyy-MMM-dd";
editor.Width = 270;
}
}
}
protected override void OnDeactivated() {
Frame.GetController<MyFilterController>().dateFilterAction.CustomizeControl -=
CustomizeActionControlControllerWeb_CustomizeControl;
base.OnDeactivated();
}
}
Imports DevExpress.ExpressApp
Imports DevExpress.ExpressApp.Actions
Imports DevExpress.ExpressApp.Web.Templates.ActionContainers.Menu
Imports DevExpress.Web
'...
Public Class CustomizeActionControlControllerWeb
Inherits Controller
Protected Overrides Sub OnActivated()
MyBase.OnActivated()
AddHandler Frame.GetController(Of MyFilterController)().dateFilterAction.CustomizeControl,
AddressOf CustomizeActionControlControllerWeb_CustomizeControl
End Sub
Private Sub CustomizeActionControlControllerWeb_CustomizeControl(ByVal sender As Object,
ByVal e As CustomizeControlEventArgs)
Dim actionItem As ParametrizedActionMenuActionItem = TryCast(e.Control,
ParametrizedActionMenuActionItem)
If actionItem IsNot Nothing Then
Dim editor As ASPxDateEdit = TryCast(actionItem.Control.Editor, ASPxDateEdit)
If editor IsNot Nothing Then
editor.UseMaskBehavior = True
editor.EditFormat = EditFormat.DateTime
editor.EditFormatString = "yyyy-MMM-dd"
editor.Width = 270
End If
End If
End Sub
Protected Overrides Sub OnDeactivated()
RemoveHandler Frame.GetController(Of MyFilterController)().dateFilterAction.CustomizeControl,
AddressOf CustomizeActionControlControllerWeb_CustomizeControl
MyBase.OnDeactivated()
End Sub
End Class
要指定日期时间格式,请使用Unicode日期字段符号表中的符号或DevExtreme库支持的预定义格式。
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using System.Collections.Generic;
// ...
public class CustomizeActionControlControllerMobile : Controller {
protected override void OnActivated() {
base.OnActivated();
MyFilterController controller = Frame.GetController<MyFilterController>();
if (controller != null) {
controller.dateFilterAction.CustomizeControl =
CustomizeActionControlControllerMobile_CustomizeControl;
}
}
private void CustomizeActionControlControllerMobile_CustomizeControl(object sender,
CustomizeControlEventArgs e) {
List<object> controls = (List<object>)e.Control;
Dictionary<string, object> editor = (Dictionary<string, object>)controls[1];
editor["displayFormat"] = "longdate";
}
protected override void OnDeactivated() {
MyFilterController controller = Frame.GetController<MyFilterController>();
if (controller != null) {
controller.dateFilterAction.CustomizeControl -=
CustomizeActionControlControllerMobile_CustomizeControl;
}
base.OnDeactivated();
}
}
Imports DevExpress.ExpressApp
Imports DevExpress.ExpressApp.Actions
Imports System.Collections.Generic
' ...
Public Class CustomizeActionControlControllerMobile
Inherits Controller
Protected Overrides Sub OnActivated()
MyBase.OnActivated()
Dim controller As MyFilterController = Frame.GetController(Of MyFilterController)()
If controller IsNot Nothing Then
AddHandler controller.dateFilterAction.CustomizeControl, _
AddressOf CustomizeActionControlControllerMobile_CustomizeControl
End If
End Sub
Private Sub CustomizeActionControlControllerMobile_CustomizeControl(ByVal sender As Object, _
ByVal e As CustomizeControlEventArgs)
Dim controls As List(Of Object) = CType(e.Control, List(Of Object))
Dim editor As Dictionary(Of String, Object) = DirectCast(controls(1), Dictionary(Of String, Object))
editor("displayFormat") = "longdate"
End Sub
Protected Overrides Sub OnDeactivated()
Dim controller As MyFilterController = Frame.GetController(Of MyFilterController)()
If controller IsNot Nothing Then
RemoveHandler controller.dateFilterAction.CustomizeControl, _
AddressOf CustomizeActionControlControllerMobile_CustomizeControl
End If
MyBase.OnDeactivated()
End Sub
End Class