EPR类企业管理系统

在我们现有系统基础上或全新开发,提供定制服务
为您的企业高效快速实施ERP,WMS,MES,CRM管理系统
全面管控物料仓库、销售业务、采购业务、仓库业务
生产过程、质量检验、组织架构、业务报表


定制
QQ:460-3528

开发
QQ群:3360-90194

源码
微信:136-3650-3721

用代码创建的预定义状态转换

本主题描述如何在代码中创建预定义的状态机。用户无法更改预定义的状态机。要了解如何在运行时定义状态机,请参阅“运行时指定的用户定义状态转换”主题。

重点

在某些情况下,与定义编码状态机相比,使用SingleChoiceAction操作或一组SimpleAction操作创建自定义控制器会更简单,更直接。因此,如果您需要定义一个静态状态管理过程,该过程不应由用户更改,请首先考虑这种方法,而不要使用“状态机”模块。

也可以看看:

添加一个简单的动作

添加参数化操作

如何:在详细视图布局中包括动作

注意

要查看实际的示例,请默认参考位于%PUBLIC%\ Documents \ DevExpress演示19.2 \ Components \ eXpressApp Framework \ FeatureCenter文件夹中的Feature Center演示的“状态机”部分,或在线参考Feature Center演示。

以下代码定义了一个简单的Task业务类,该业务类可以具有不同的状态,例如未开始进行中完成等。

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); }
    }
}

要为此类创建状态机,请执行以下步骤。

  1. 声明一个StateMachine <T>类后代,并使用泛型类型参数指定目标业务类。覆盖Name属性以提供状态机的文本描述。

    using DevExpress.ExpressApp.StateMachine.NonPersistent;
    //...
    public class TaskStatusStateMachine : StateMachine<Task> {
        public override string Name { 
            get { return "Change status to"; } 
        }
    }
    
  2. 确定将哪个业务类属性用作状态属性。为了发挥作用,状态机必须能够区分对象状态。这就是为什么您需要指定一个属性,其值将代表不同的对象状态。这可以是枚举类型的属性,也可以是引用属性。在此示例中,Status属性是理想的选择。因此,它用作状态属性,因此,其值将用作状态标记。请注意,不同的状态必须使用不同的标记对象。要指定状态属性,请覆盖StatePropertyName属性。

    public class TaskStatusStateMachine : StateMachine<Task> {
        //...
        public override string StatePropertyName { 
            get { return "Status"; }
        }
    }
    
  3. 声明一组允许的状态以及它们之间的过渡。状态是状态类实例,过渡是过渡类实例。状态属于状态机,并具有关联的标题和标记。每个状态都有一组指定了可能目标状态的允许过渡。在这个例子中,它不应该是可能的任务,成为完成的,直到它是在进步的,所以在建状态,不应该包含完成过渡。

    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; } 
        }
    }
    

    您在状态机的构造函数定义的状态,转换和外观规则后,将它们添加到机器的国家收藏。覆盖StartState属性以为新创建的对象指定初始状态。

  4. 状态机还可以选择具有与其状态相关联的“条件外观”规则。这些规则由StateAppearance实例表示。

    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. 在目标业务类中实现IStateMachineProvider接口。接口的唯一成员-GetStateMachines方法-返回可用于该业务类的所有状态机的列表。

    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;
        }
    }
    

状态机模块将在任务视图中显示ChangeStateAction操作。该Action由StateMachineController提供。

StateMachine-ShowActionsInToolBar

注意

StateMachineController的目的不是使用它来执行额外的逻辑TransitionExecutingTransitionExecuted事件。而是将您的自定义代码放在所需业务类属性的设置器中。

您可以选择实现IStateMachineUISettings接口,并将其ExpandActionsInDetailView属性设置为true

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

在这种情况下,目标业务类的“详细信息视图”将包含与可用状态转换相对应的单独的“简单操作”

StateMachine-ShowActionsInPanel

转载保留此链接,注明出处