), is designed to provide elements (and hence documents) with consistent support for
of all operations, which the user or the programmer can possibly perform with an element or element attribute. This service is represented by the
class. The reason for which the element abstraction has been chosen for base of the history service is that elements can be uniquely identified.
The history service works as a recorder of operations (user or programmer actions). The abstraction of an operation is represented by the NOperation class. All types of operations, which the history service can record must derive from NOperation.
The history service maintains two operations stacks:
The history service recording obeys to the following rules:
The history service can virtually operate with an unlimited number of operations. You can however limit the number of recorded undoable operations by setting the MaxUndoLevels property to the number of actions you want the history service to remember:
C# |
Copy Code
|
// instruct the history service to remember the last 200 actions
historyService.MaxUndoLevels = 200;
|
Visual Basic |
Copy Code
|
' instruct the history service to remember the last 200 actions
historyService.MaxUndoLevels = 200
|
Primitive Operations
The Nevron DOM implements a set of primitive operations, which are designed to record any user actions, which can be performed on an element or an element attribute. They can be classified in the following categories:
You can of course implement your own history operations - the only requirement is that they must be derived from the NOperation class.
Transactions are groups of operations, which are undone and redone as if they were a single operation. Transactions are represented by the NTransaction class (derived from NOperation). The history service provides three methods, which help you easily work with transactions - they are:
-
StartTransaction - opens a new transaction. Internally this creates a new transaction and pushes it in the
transactions stack. If there is an opened transaction, the history service will automatically record all operations in it (instead of recording them in the undo stack).
-
Commit - closes the last opened transaction. Internally this method pops the last transaction from the transactions stack and pushes it in the undo stack.
-
Rollback - aborts the last opened transaction. Internally this method pops the last transaction from the transactions stack and undoes all operations, which it contains in reverse order. The rollback method does not record any operation in the undo stack. The effect of rollback is that the object state, which is monitored by the history service is reverted to the state when the transaction was started.
The following code snipped demonstrates a typical transaction based method:
C# |
Copy Code
|
public bool MyTransactionBasedMethod()
{
// start a new transaction
historyService.StartTransaction("My transaction");
try
{
// do something that can fail
...
}
catch (Exception ex)
{
// if something went wrong - restore the state as
// it was when the transaction was started
historyService.Rollback();
return false;
}
// if everything went ok - commit the transaction
historyService.Commit();
return true;
}
|
Visual Basic |
Copy Code
|
Public Function MyTransactionBasedMethod() As Boolean
' start a new transaction
historyService.StartTransaction("My transaction")
Try
' do something that can fail
...
Catch ex As Exception
' if something went wrong - restore the state as
' it was when the transaction was started
historyService.Rollback()
Return False
End Try
' if everything went ok - commit the transaction
historyService.Commit()
Return True
End Function
|
In order to make it easier for you to implement custom elements and attributes, which support history, the NAttribute class and the core INElement implementations found in the respective Nevron product, provide a set of protected methods, which safely call the respective methods of the history service. The following code example demonstrates how to implement a custom history aware attribute:
C# |
Copy Code
|
class MyAttribute : NAttribute
{
public bool BoolProperty
{
get
{
return boolField;
}
set
{
if (value == boolField)
return;
// fire a property changing event and see if the user allows the change
// OnPropertyChanging is implemented by NAttribute
if (OnPropertyChanging("BoolProperty", value) == false)
return;
// record the property value before it is changed
// RecordProperty is implemented by NAttribute
RecordProperty("BoolProperty");
boolField = value;
// notify the user that the property has changed
// OnPropertyChanged is implemented by NAttribute
OnPropertyChanged("BoolProperty");
}
}
private bool boolField;
}
|
Visual Basic |
Copy Code
|
Class MyAttribute Inherits NAttribute
Public Property BoolProperty() As Boolean
Get
Return boolField
End Get
Set(ByVal Value As Boolean)
If Value = boolField Then
Return
End If
' fire a property changing event and see if the user allows the change
' OnPropertyChanging is implemented by NAttribute
If OnPropertyChanging("BoolProperty", Value) = False Then
Return
End If
' record the property value before it is changed
' RecordProperty is implemented by NAttribute
RecordProperty("BoolProperty")
boolField = Value
' notify the user that the property has changed
' OnPropertyChanged is implemented by NAttribute
OnPropertyChanged("BoolProperty")
End Set
End Property
Private boolField As Boolean
End Class
|