How to: Create an Action Using the Action Attribute
- 6 minutes to read
This example demonstrates how to create an Action within a persistent class declaration (i.e., how to convert a persistent class method into a SimpleAction or PopupWindowShowAction).
#Important Notes on Using the Action Attribute
Actions created with the ActionAttribute are not designed to operate in List Views without any selected objects. The attribute’s ActionAttribute.SelectionDependencyType parameter can be set either to RequireSingleObject
or RequireMultipleObjects
(see MethodActionSelectionDependencyType). To create an Action that does not require the selected object, add a Controller and implement an Action in it (see Add a Simple Action and Add an Action that Displays a Pop-Up Window).
ActionAttribute is primarily used in simple scenarios when you execute logic based on data available within the business class context (for instance, modify class properties). ActionAttribute is not suitable for any UI-related logic and complex user interactions. It is also not possible to access XafApplication, Views, and other XAF UI-related entities within the business class code, because it violates the separation of concerns principle and is against the MVC architecture (your data model should not be tied to the UI). To access XafApplication, Views, and other UI-related entities, implement Controllers with Actions.
#Create A Simple Action
Add a Task
business class to your project.
[DefaultClassOptions,ImageName("BO_Task"),DefaultProperty(nameof(Subject))]
public class Task : BaseObject {
public virtual string Subject { get; set; }
public virtual bool IsCompleted { get; set; }
}
// Make sure that you use options.UseChangeTrackingProxies() in your DbContext settings.
Implement an Action that changes the IsCompleted
property to true
. Add the following Complete
method to the Task
class and decorate it with the ActionAttribute.
[Action(Caption="Complete", TargetObjectsCriteria = "Not [IsCompleted]")]
public void Complete() {
IsCompleted = true;
}
Such methods are automatically collected from business classes by the ObjectMethodActionsViewController
. This controller creates the Task.Complete
Action, that invokes the Complete
method for each selected Task
. Note the use of the ActionAttribute.TargetObjectsCriteria parameter. The Action is disabled for Tasks
that are already completed (the IsCompleted
property is true
). You can pass other parameters to customize the Action’s look and behavior.
The images below illustrate the Complete Action in the UI.
ASP.NET Core Blazor
WinForms
ASP.NET Web Forms
#Create an Action that Displays a Pop-up Dialog
Extend the Task
class with two additional properties (Deadline
and Comments
) to demonstrate a more complex scenario.
using DevExpress.ExpressApp.Model;
// ...
public virtual DateTime? Deadline { get; set; }
[FieldSize(FieldSizeAttribute.Unlimited),ModelDefault("AllowEdit", "False")]
public virtual string Comments { get; set; }
// Make sure that you use options.UseChangeTrackingProxies() in your DbContext settings.
Implement an Action that postpones the Deadline
by a specified number of days and updates the Comments
text. First, declare the following non-persistent class that holds parameters to be specified when a user postpones a Task
.
using DevExpress.ExpressApp.DC;
// ...
[DomainComponent]
public class PostponeParametersObject {
public PostponeParametersObject() { PostponeForDays = 1; }
public uint PostponeForDays { get; set; }
[FieldSize(FieldSizeAttribute.Unlimited)]
public string Comment { get; set; }
}
Then, add the following Postpone
method to the Task
class. This method takes a parameter of the PostponeParametersObject
type and is decorated with the Action
attribute.
[Action(Caption = "Postpone",
TargetObjectsCriteria = "[Deadline] Is Not Null And Not [IsCompleted]")]
public void Postpone(PostponeParametersObject parameters) {
if (Deadline.HasValue && !IsCompleted && (parameters.PostponeForDays > 0)) {
Deadline += TimeSpan.FromDays(parameters.PostponeForDays);
Comments += String.Format("Postponed for {0} days, new deadline is {1:d}\r\n{2}\r\n",
parameters.PostponeForDays, Deadline, parameters.Comment);
}
}
As a result, the Task.Postpone Action, that accompanies the Task
Views, is automatically created. This Action invokes a dialog with the PostponeParametersObject Detail View and executes the Postpone
method after a user specifies the parameters and clicks OK. The following images illustrate this.
ASP.NET Core Blazor
WinForms
ASP.NET Web Forms
Tip
If it is necessary to reorder parameters displayed in a popup dialog, modify the layout of a parameter object’s Detail View in the Model Editor. In the example above, the appropriate Detail View node is Postpone
#Access the current object instance
If you declare a PostponeParametersObject
constructor that takes a parameter of type Task
, the current Task
instance is passed to this constructor when a user initiates the Action.