c# - 在 C# 或 VB.NET 中使用 'System.Activities.Statements.StateMachine' 类的示例

标签 c# .net vb.net state-machine undo-redo

我觉得有必要询问 System.Activities.Statements.StateMachine 的完整限定示例用法类来存储和恢复 Control 的状态实例(这意味着,我想存储控件的状态以替换基于控件属性和“命令”的典型撤消/重做方法)。

我一直在 Google 上搜索自制的状态机实现,找到了很多,但后来我在 .NET Framework 类库中发现了 Microsoft 的这个实现(现在我没有理由依赖任何自制实现来重新发明轮子),但是,MSDN 没有代码示例来介绍该类的用法,我在 Google 上也没有找到任何结果来证明它的用法(以及一小段代码示例我在其他一些相关成员的 MSDN 上看到的我根本不明白我应该如何使用它们)。

然后现在我简直是盲人,试图通过反复试验来学习如何使用该类及其相关成员。

下面是我目前尝试的方法,我坚持要“注册”obj 的状态。变量,具体在System.Activities.OutArgument.SetSystem.Activities.OutArgument.Get采用 ActivityContext 的方法作为第一个参数,我不知道应该传递给它们什么值(在我下面的代码中,调用这些方法会引发异常,因为该值不能为 null)。

C#(由在线代码翻译器翻译,可能有语法错误):

using System.Activities;
using System.Activities.Statements;

// Create a container for statemachines
StateMachine sm = new StateMachine();

// Declare an object to test its state...
string obj = null;

// Modify the state of 'obj'.
obj = "hello";

// Save 1st state of 'obj'.
Activity<string> act1 = obj;
act1.Result = new OutArgument<string>();
act1.Result.Set(null, obj);
State state1 = new State();
state1.Entry = act1;

// Modify the state of 'obj'.
obj = "hello world";

// Save 2nd state of 'obj'.
Activity<string> act2 = obj;
act2.Result = new OutArgument<string>();
act2.Result.Set(null, obj);
State state2 = new State();
state2.Entry = act2;

// Add saved states into the statemachine collection.
sm.States.Add(state1);
sm.States.Add(state2);

// Modify the state of 'obj'.
obj = string.Empty;

// Restore last saved state of 'obj'.
obj = ((Activity<string>)sm.States.Last().Entry).Result.Get(null);

VB.NET:

Imports System.Activities
Imports System.Activities.Statements

' Create a container for statemachines
Dim sm As New StateMachine()

' Declare an object to test its state...
Dim obj As String

' Modify the state of 'obj'.
obj = "hello"

' Save 1st state of 'obj'.
Dim act1 As Activity(Of String) = obj
act1.Result = New OutArgument(Of String)
act1.Result.Set(Nothing, obj)
Dim state1 As New State()
state1.Entry = act1

' Modify the state of 'obj'.
obj = "hello world"

' Save 2nd state of 'obj'.
Dim act2 As Activity(Of String) = obj
act2.Result = New OutArgument(Of String)
act2.Result.Set(Nothing, obj)
Dim state2 As New State()
state2.Entry = act2

' Add saved states into the statemachine collection.
sm.States.Add(state1)
sm.States.Add(state2)

' Modify the state of 'obj'.
obj = String.Empty

' Restore last saved state of 'obj'.
obj = DirectCast(sm.States.Last().Entry, Activity(Of String)).Result.Get(Nothing)

...还有一些说明,例如 Activity<string> act1 = obj;/Dim act1 As Activity(Of String) = obj我不确定这样做是否正确。

PS:请注意,在上面的代码中,我使用了一个 String 变量只是为了简化操作,但我需要保存和恢复 Control 的状态。正如我之前解释的那样。

最佳答案

System.Activities 命名空间属于 Windows Workflow Foundation .此命名空间中的事件类用于构建工作流,例如 SharePoint workflows例如。

StateMachine 类是多个子事件的容器,这些子事件共同构成了一个 State Machine Workflow .

定义工作流后,您可以使用工作流引擎使用 WorkflowInvokerWorkflowApplication 运行它。来自docs :

WorkflowInvoker provides a simple way for invoking a workflow as if it were a method call and can be used only for workflows that do not use persistence. WorkflowApplication provides a richer model for executing workflows that includes notification of life-cycle events, execution control, bookmark resumption, and persistence.

您引用的 ActivityContext 包含有关工作流运行时的信息,例如执行事件的主机。运行时会填写信息,因此您不能自己注入(inject)一些东西。

您找不到太多使用 StateMachine 类的示例的原因是大多数工作流都是使用创建 .XAML 文件的图形设计器构建的,我认为很多工作流都是使用仅代码。

现在,鉴于所有这些,您可以看到对于您的场景来说,这不是一个很好的选择,当然也不是为撤消/重做用例设计的。

有些框架/库可能更合适,比如 this来自 PostSharp。

关于c# - 在 C# 或 VB.NET 中使用 'System.Activities.Statements.StateMachine' 类的示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46085701/

相关文章:

c# - 检测 Apple 订阅过期

c# - 使用自定义解析器时程序集不允许部分信任的调用者

c# - 通用 WinRT 应用程序中的 AppBarButton 异常未触发未处理的异常事件

c# - 如何将 SAML XML token 字符串转换为 SecurityToken 或 ClaimsPrincipal 实例?

c# - 需要转换类型,但 Task<TUser> 和 Task<IUser> 是否相同?

vb.net - 在 SQL Server Reporting Services (VB.Net) 中查找上一个日历月的第一天和最后一天

asp.net - 将单元测试慢慢集成到项目中所需采取的步骤

c# - VB.NET 是否具有等同于 c# 的多行字符串声明语法?

c# - 正则表达式,强制文本垂直

c# - JSON 中出现意外标记