学习021-02-03 Predefined State Transitions Created in Code (在代码中创建的预定义状态转换)

Predefined State Transitions Created in Code (在代码中创建的预定义状态转换)

This topic describes how to create a predefined State Machine in code. A predefined State Machine cannot be changed by users. For information how to define a state machine at runtime, refer to the User-Defined State Transitions Specified at Runtime topic instead.
本主题介绍如何在代码中创建预定义状态机。预定义状态机不能被用户修改。有关如何在运行时定义状态机的信息,请参阅“运行时指定的用户定义状态转换”主题。

**Important **
In certain scenarios, creating a custom Controller with the SingleChoiceAction Action or a set of SimpleAction Actions can be simpler and more straightforward than defining a coded State Machine. So, if you need to define a static state management process that should not be changed by users, consider this approach first instead of using the State Machine module.

在某些场景中,使用SingleChoiceAction动作或一组SimpleAction动作创建自定义控制器,可能比定义编码状态机更简单直接。因此,若需定义一个不应被用户修改的静态状态管理流程,建议优先考虑此方法,而非使用状态机模块。
See Also:
另请参见:
Add a Simple Action
添加简单动作
Add a Parametrized Action
添加参数化动作
How to: Include an Action to a Detail View Layout
如何:将动作包含到详情视图布局中

Note
To see this example in action, refer to the State Machine section of the Feature Center demo located in the %PUBLIC%\Documents\DevExpress Demos 24.1\Components\XAF\FeatureCenter.NETFramework.XPO folder by default, or refer to the Feature Center demo online.

要查看实际运行的示例,请参考Feature Center演示中的“状态机”部分,其默认位于%PUBLIC%\Documents\DevExpress Demos 24.1\Components\XAF\FeatureCenter.NETFramework.XPO文件夹,或在线参考Feature Center演示。

The following code defines a simple Task business class, which can have different states such as not started, in progress, completed, etc.
以下代码定义了一个简单的Task业务类,它可以具有不同的状态,如未开始、进行中、已完成等。

C# (EF Core)  
using DevExpress.Persistent.Base;  
using DevExpress.Persistent.BaseImpl.EF;  
using System.ComponentModel.DataAnnotations;  
//...  
public enum TaskStatus { Draft, NotStarted, InProgress, Paused, Completed, Dropped }  


[DefaultClassOptions,ImageName("BO_Task")]  
public class Task : BaseObject {  
    public virtual string Subject { get; set; }  
    public virtual TaskStatus Status { get; set; }  
}  


// Make sure that you use options.UseChangeTrackingProxies() in your DbContext settings.  
C# (XPO)  
using DevExpress.Persistent.Base;  
using DevExpress.Persistent.BaseImpl;  
using DevExpress.Xpo;  
//...  
public enum TaskStatus { Draft, NotStarted, InProgress, Paused, Completed, Dropped }  


[DefaultClassOptions, ImageName("BO_Task")]  
public class Task : BaseObject {  
    public Task(Session session) : base(session) { }  
    public string Subject {  
        get { return GetPropertyValue<string>(nameof(Subject)); }  
        set { SetPropertyValue<string>(nameof(Subject), value); }  
    }  
    public TaskStatus Status {  
        get { return GetPropertyValue<TaskStatus>(nameof(Status)); }  
        set { SetPropertyValue<TaskStatus>(nameof(Status), value); }  
    }  
}  

To create a state machine for this class, perform the following steps.
要为此类创建状态机,请执行以下步骤。

1.Declare a StateMachine<T> class descendant with the generic type parameter specifying the target business class. Override the Name property to specify a textual description for a state machine.
声明一个StateMachine<T>类的派生类,其泛型类型参数指定目标业务类。重写Name属性以指定状态机的文本描述。

C#  
using DevExpress.ExpressApp.StateMachine.NonPersistent;  
//...  
public class TaskStatusStateMachine : StateMachine<Task> {  
    public override string Name {  
        get { return "Change status to"; }  
    }  
}  

2.Decide which business class property should be used as a state property. To function, a state machine must be able to distinguish between object states. This is why you need to specify a property whose values will represent different object states. This can be either an enumeration-typed property or a reference property. In this example, the Status property is a perfect candidate. Thus, it is used as a state property, and consequently, its values will be used as state markers. Note that different states must use different marker objects. To specify a state property, override the StatePropertyName property.
确定应将业务类的哪个属性用作状态属性。状态机要正常工作,必须能够区分对象的不同状态。因此,需要指定一个属性,其值将表示对象的不同状态。该属性可以是枚举类型属性或引用属性。在本示例中,Status属性是理想选择。因此,它被用作状态属性,其值将作为状态标记。注意,不同的状态必须使用不同的标记对象。要指定状态属性,请重写StatePropertyName属性。

C#  
public class TaskStatusStateMachine : StateMachine<Task> {  
    //...  
    public override string StatePropertyName {  
        get { return "Status"; }  
    }  
}  

3.Declare a set of allowed states and transitions between them. States are State class instances and transitions are Transition class instances. A state belongs to a state machine and has an associated caption and a marker. Each state has a collection of allowed transitions that specify possible target states. In this example, it should not be possible for a task to become completed until it is in progress, so the in progress state should not contain a completed transition.
声明一组允许的状态以及它们之间的转换。状态是State类的实例,转换是Transition类的实例。一个状态属于一个状态机,并具有关联的标题和标记。每个状态都有一个允许的转换集合,用于指定可能的目标状态。在本示例中,任务在进行中之前不能变为已完成状态,因此进行中状态不应包含到已完成状态的转换。

C#  
using DevExpress.ExpressApp.StateMachine;  
//...  
public class TaskStatusStateMachine : StateMachine<Task> {  
    //...  
    private IState startState;  
    public TaskStatusStateMachine(IObjectSpace objectSpace) : base(objectSpace) {  
        startState = new State(this, TaskStatus.Draft);  


        IState notStartedState = new State(this, "Not Started", TaskStatus.NotStarted);  
        IState inProgressState = new State(this, "In Progress", TaskStatus.InProgress);  
        IState pausedState = new State(this, TaskStatus.Paused);  
        IState completedState = new State(this, TaskStatus.Completed);  
        IState droppedState = new State(this, TaskStatus.Dropped);  


        startState.Transitions.Add(new Transition(notStartedState));  
        notStartedState.Transitions.Add(new Transition(startState));  
        notStartedState.Transitions.Add(new Transition(inProgressState));            
        inProgressState.Transitions.Add(new Transition(pausedState));  
        inProgressState.Transitions.Add(new Transition(completedState));  
        inProgressState.Transitions.Add(new Transition(droppedState));  
        pausedState.Transitions.Add(new Transition(inProgressState));  
        droppedState.Transitions.Add(new Transition(notStartedState));  


        States.Add(startState);  
        States.Add(notStartedState);  
        States.Add(inProgressState);  
        States.Add(pausedState);  
        States.Add(completedState);  
        States.Add(droppedState);  
    }  
    public override IState StartState {  
        get { return startState; }  
    }  
}  

After you have defined states, transitions, and appearance rules in a state machine constructor, add them to the machine’s States collection. Override the StartState property to specify the initial state for newly created objects.
在状态机构造函数中定义状态、转换和外观规则后,将它们添加到状态机的States集合中。重写StartState属性以指定新创建对象的初始状态。

4.A state machine can optionally have Conditional Appearance rules associated with its states. These rules are represented by StateAppearance instances.
状态机可以选择性地为其状态关联条件外观规则。这些规则由StateAppearance实例表示。

C#  
public class TaskStatusStateMachine : StateMachine<Task> {  
    //...  
    public TaskStatusStateMachine(IObjectSpace objectSpace) : base(objectSpace) {  
        //...        
        StateAppearance inProgressAppearance = new StateAppearance(inProgressState);  
        inProgressAppearance.TargetItems = "Subject";  
        inProgressAppearance.Enabled = false;  
        StateAppearance completedAppearance = new StateAppearance(completedState);  
        completedAppearance.TargetItems = "Subject";  
        completedAppearance.Enabled = false;  
        StateAppearance pausedAppearance = new StateAppearance(pausedState);  
        pausedAppearance.TargetItems = "*";  
        pausedAppearance.BackColor = System.Drawing.Color.Yellow;  
    }  
}  

5.Implement the IStateMachineProvider interface in the target business class. The interface’s only member - GetStateMachines method - returns a list of all state machines available for the business class.
在目标业务类中实现IStateMachineProvider接口。该接口的唯一成员——GetStateMachines方法——返回该业务类可用的所有状态机的列表。

C# (EF Core)  
using System.Collections.Generic;  
using DevExpress.ExpressApp.EFCore;  
using DevExpress.ExpressApp.StateMachine;  
using DevExpress.ExpressApp.EFCore;  
//...  
public class Task : BaseObject, IStateMachineProvider {  
    //...  
    public IList<IStateMachine> GetStateMachines() {  
        List<IStateMachine> result = new List<IStateMachine>();  
        result.Add(new TaskStatusStateMachine(EFCoreObjectSpace.FindObjectSpaceByObject(this)));  
        return result;  
    }  
}  


// Make sure that you use options.UseChangeTrackingProxies() in your DbContext settings.  
C# (XPO)  
using System.Collections.Generic;  
//...  
public class Task : BaseObject, IStateMachineProvider {  
    //...  
    public IList<IStateMachine> GetStateMachines() {  
        List<IStateMachine> result = new List<IStateMachine>();  
        result.Add(new TaskStatusStateMachine(XPObjectSpace.FindObjectSpaceByObject(this)));  
        return result;  
    }  
}  

The State Machine module will display the ChangeStateAction Action in Task Views. The Action is provided by the StateMachineController.
状态机模块将在Task视图中显示ChangeStateAction动作。该动作由StateMachineController提供。

在这里插入图片描述

*Note
The StateMachineController is not designed to execute additional logic using its TransitionExecuting and TransitionExecuted events. Instead, place your custom code in the setter of the desired business class property. *
StateMachineController并非设计为使用其TransitionExecuting和TransitionExecuted事件执行额外逻辑。相反,请将自定义代码放在所需业务类属性的setter中。

You can optionally implement the IStateMachineUISettings interface and set its ExpandActionsInDetailView property to true.
您可以选择性地实现IStateMachineUISettings接口,并将其ExpandActionsInDetailView属性设置为true。

C#  
public class TaskStatusStateMachine : StateMachine<Task>, IStateMachineUISettings {  
    //...  
    public bool ExpandActionsInDetailView {  
        get { return true; }  
    }  
}  

In this instance, the target business class Detail Views will contain separate Simple Actions corresponding to available state transitions.
在这种情况下,目标业务类的详情视图将包含与可用状态转换对应的独立Simple Actions。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汤姆•猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值