I feel in the need to ask for a full qualified example usage of the System.Activities.Statements.StateMachine class to store and restore the state of a Control
instance (this means, I would like to store the state of a Control to replace the typical undo/redo methodology based on control properties and "commands").
I've been searching for home-made state-machine implementations on Google, I found a lot, but then I discovered this implementation of Microsoft in the .NET Framework Class Library (then now I have no reason to depend on any home-made implementation to reinvent the wheel), however, the MSDN has not a code sample to introduce on the usage of that class, and I didn't found any result on Google that demonstrates its usage (and the little pieces of code samples that I seen in the MSDN on some other related members I didn't understood it at all how do I should use them).
Then now I'm literally blind, trying to learn how to use that class and its related members by trial-and-error.
This below is what I tried by the moment, I'm stuck at the intent to "register" the state of the obj
variable, concretelly at the System.Activities.OutArgument.Set and System.Activities.OutArgument.Get methods that takes a ActivityContext as first parameter and I don't know what value I should pass to them (in my code below a call to those methods throws an exception because the value cannot be null).
C# (translated by an online code translator, can have syntax errors):
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)
...Also some instructions like Activity<string> act1 = obj;
/ Dim act1 As Activity(Of String) = obj
I'm not sure if that is the right manner to do it.
PS: Note that in the code above I've used a String variable just to simplify things, but I require to save and restore the state of a Control
as I explained before.
The
System.Activities
namespace belongs to the Windows Workflow Foundation. Activity classes in this namespace are used to build workflows, like SharePoint workflows for example.The
StateMachine
class is a container for several child activities that together form a State Machine Workflow.Once you have defined a workflow you can run it using the Workflow Engine using a
WorkflowInvoker
or aWorkflowApplication
. From the docs:The
ActivityContext
you refer to holds information about the workflow runtime, e.g. the host that executes the activity. The runtime fills in the information so you cannot inject something yourself.The reason that you won't find much examples of using the
StateMachine
class is that most workflows are build using a graphical designer that creates .XAML files and I don't think many are build using code only.Now, given all of this you can see that for your scenario this is not a good fit and certainly not designed for undo/redo use cases.
There are framework/libraries that might be a better fit, like this from PostSharp.