tag propiedad c# .net vb.net winforms undo-redo

c# - propiedad - ¿Cómo empezar a usar la clase.NET Framework UndoEngine?



console.title c# (3)

Encuentre una implementación de UndoEngine y cómo usarla aquí: https://github.com/icsharpcode/SharpDevelop/search?q=ReportDesignerUndoEngine&ref=cmdform

HTH

Hoy he descubierto que el FW 4.5 tiene su propio administrador Undoredo (si lo entendí bien) http://msdn.microsoft.com/en-us/library/System.ComponentModel.Design.UndoEngine%28v=vs.110%29.aspx

Bueno, no puedo encontrar ningún ejemplo sobre cómo empezar a usar esta clase solo para hacer un simple deshacer / rehacer un control basado en texto, conozco otras alternativas para hacer cosas que se pueden deshacer, pero solo quiero aprender a usar esto.

Cuando trato de usar el constructor, tiene que pasar cualquier parámetro, y el Intellisense no me muestra ningún método para la clase System.ComponentModel.Design.UndoEngine , realmente no sé cómo podría usarlo.

¿Alguien podría ilustrar el nuestro con un ejemplo para C# o VBNET ? (Prefiero la documentación VBNET si es posible, por favor)



UndoEngine es una clase abstracta, Visual Studio y los diseñadores han implementado UndoEngine a su manera, y estos deben ser privados o no estar disponibles para su redistribución. No podrá usarlo, de hecho, la clase abstracta es solo una interfaz con poca implementación, no es en absoluto un marco de deshacer.

Aún tiene que escribir su propia gestión de deshacer, sin embargo, el beneficio de derivar su motor de deshacer de la clase UndoEngine es que puede ser fácilmente alojado / integrado con VS y otros editores basados ​​en MS.

  1. Si desea proporcionar una experiencia de edición dentro del editor de documentos de Visual Studio, entonces tiene que derivar su clase de marco de Deshacer de UndoEngine, VS destacará automáticamente los botones de deshacer / rehacer de deshabilitación y llamará a los métodos de deshacer / rehacer en su clase.
  2. Si desea utilizar UndoEngine dentro de su propia aplicación, UndoEngine no lo ayudará en nada, tendrá que escribir todas las funciones por su cuenta. UndoEngine solo administra la pila de Deshacer / Rehacer, el trabajo real está dentro de UndoUnit. Se basa en el concepto de Unidad de trabajo, donde cada una de sus acciones debería representar un trabajo que se puede deshacer.

La implementación más simple de UndoEngine

Digamos que está cambiando una variable global,

// following code uses big UndoUnit public void SetGlobalVariable(object v){ var oldValue = GlobalVariable; GlobalVariable = v; var action = new UndoUnit{ UndoAction = ()=>{ GlobalVariable = oldValue; }, RedoAction = ()=>{ GlobalVariable = v; } }; UndoManager.Add(action); } /// <summary> /// Used to indicates the designer''s status /// </summary> public enum UndoUnitState { Undoing, Redoing, } /// <summary> /// A UndoUnitBase can be used as a IOleUndoUnit or just a undo step in /// a transaction /// </summary> public class UndoUnitBase : IOleUndoUnit { public Action UndoAction {get;set;} public Action RedoAction {get;set;} private string name = null; private Guid clsid = Guid.Empty; private bool inDoAction = false; private bool isStillAtTop = true; private UndoUnitState unitState = UndoUnitState.Undoing; protected UndoUnit UnitState { get { return unitState; } set { unitState = value; } } /// <summary> /// </summary> /// <param name="undoManager"></param> /// <param name="name"></param> internal UndoUnitBase(string name) { this.name = name; } ~UndoUnitBase() { } /// <summary> /// </summary> protected bool InDoAction { get { return inDoAction; } } public string UndoName { get { return name; } set { this.name = value; } } public Guid Clsid { get { return clsid; } set { clsid = value; } } /// <summary> /// This property indicates whether the undo unit is at the top (most recently added to) /// the undo stack. This is useful to know when deciding whether undo units for operations /// like typing can be coallesced together. /// </summary> public bool IsStillAtTop { get { return isStillAtTop; } } /// <summary> /// This function do the actual undo, and then revert the action to be a redo /// </summary> /// <returns>objects that should be selected after DoAction</returns> protected abstract void DoActionInternal(); /// <devdoc> /// IOleUndoManager''s "Do" action. /// </devdoc> void IOleUndoUnit.Do(IOleUndoManager oleUndoManager) { Do(oleUndoManager); } protected virtual int Do(IOleUndoManager oleUndoManager) { try { if(unitState== UndoUnitState.Undoing){ UndoAction(); }else{ RedoAction(); } unitState = (unitState == UndoUnitState.Undoing) ? UndoUnitState.Redoing : UndoUnitState.Undoing; if (oleUndoManager != null) oleUndoManager.Add(this); return VSConstants.S_OK; } catch (COMException e) { return e.ErrorCode; } catch { return VSConstants.E_ABORT; } finally { } } /// <summary> /// </summary> /// <returns></returns> void IOleUndoUnit.GetDescription(out string pBstr) { pBstr = name; } /// <summary> /// </summary> /// <param name="clsid"></param> /// <param name="pID"></param> /// <returns></returns> void IOleUndoUnit.GetUnitType(out Guid pClsid, out int plID) { pClsid = Clsid; plID = 0; } /// <summary> /// </summary> void IOleUndoUnit.OnNextAdd() { // We are no longer the top most undo unit; another one was added. isStillAtTop = false; } } public class MyUndoEngine : UndoEngine, IUndoHandler { Stack<UndoEngine.UndoUnit> undoStack = new Stack<UndoEngine.UndoUnit>(); Stack<UndoEngine.UndoUnit> redoStack = new Stack<UndoEngine.UndoUnit>(); public ReportDesignerUndoEngine(IServiceProvider provider) : base(provider) { } #region IUndoHandler public bool EnableUndo { get { return undoStack.Count > 0; } } public bool EnableRedo { get { return redoStack.Count > 0; } } public void Undo() { if (undoStack.Count > 0) { UndoEngine.UndoUnit unit = undoStack.Pop(); unit.Undo(); redoStack.Push(unit); } } public void Redo() { if (redoStack.Count > 0) { UndoEngine.UndoUnit unit = redoStack.Pop(); unit.Undo(); undoStack.Push(unit); } } #endregion protected override void AddUndoUnit(UndoEngine.UndoUnit unit) { undoStack.Push(unit); } }