texto teclas revertir rehacer recuperar qué para notas funcion eliminar deshacer cómo control combinacion comando borrado c# windows-8 microsoft-metro windows-runtime windows-store-apps

c# - teclas - Windows 8: ¿Cómo deshacer y rehacer la tinta con la funcionalidad de entintado incorporada?



recuperar texto borrado notas iphone (1)

Implementé el código de tinta en mi aplicación basado en la muestra de tinta simplificada por microsoft: http://code.msdn.microsoft.com/windowsapps/Input-simplified-ink-sample-11614bbf/view/SourceCode

Primero hice una clase que guarda los datos de una operación (dibujar / borrar / borrar) de esta manera:

public enum eInkOperation { Draw, Delete, None } public class InkOperation { public InkStroke Stroke { get; set; } //requred for drawing from undo public eInkOperation Operation { get; set; } public InkOperation(InkStroke stroke, eInkOperation inkOperation) { Stroke = stroke.Clone(); //needs to be cloned for AddStroke to work Operation = inkOperation; } }

Luego hice una pila para deshacer las operaciones de tinta y otra para las operaciones de rehacer

//stack of normal operations Stack<InkOperation> _undoStack = new Stack<InkOperation>(); //Undo action will pop them off of the undo stack and push them onto the redo stack Stack<InkOperation> _redoStack = new Stack<InkOperation>();

Cuando un usuario deshace un trazo lo empujo en la pila de rehacer y lo elimina del administrador de tinta con estos métodos:

private void RedoStackPush(InkOperation inkOperation) { inkOperation.Stroke = inkOperation.Stroke.Clone(); _redoStack.Push(inkOperation); } private void DeleteStroke(InkStroke stroke) { stroke = inkManager.GetStrokes().Last(); stroke.Selected = true; inkManager.DeleteSelected(); }

Luego, cuando el usuario hace clic en Rehacer, el trazo se saca de la pila de rehacer y se dibuja con este método:

private void DrawStroke(InkStroke stroke) { if (stroke!=null) { inkManager.Mode = InkManipulationMode.Inking; inkManager.AddStroke(stroke); } renderer.Clear(); //this renderer object smooths the strokes //and adds them as Path objects to the desired control (Grid, etc) renderer.AddInk(inkManager.GetStrokes()); }

Todo esto funciona, y el trazo se muestra de nuevo en la cuadrícula. Sin embargo, cuando trato de borrar el trazo recién rediseñado obtengo esta excepción:

AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Esto sucede en:

public void PointerMoved(PointerRoutedEventArgs e) { try { var pointerPoint = e.GetCurrentPoint(_inkingArea); var pointerEventType = InkHelpers.GetPointerEventType(e); if (pointerId == (int)pointerPoint.PointerId) { switch (inkManager.Mode) { case InkManipulationMode.Inking: case InkManipulationMode.Selecting: //process intermediate points var intermediatePoints = e.GetIntermediatePoints(_inkingArea); for (int i = intermediatePoints.Count - 1; i >= 0; i--) { inkManager.ProcessPointerUpdate(intermediatePoints[i]); } //live rendering renderer.UpdateLiveRender(pointerPoint); break; case InkManipulationMode.Erasing: //check if something has been erased //in erase mode InkManager.ProcessPointerUpdate returns an invalidate rectangle: //if it is not degenerate, something has been erased //in erase mode don''t bother processing intermediate points //If inkManager.ProcessPointerUpdate throws an exception, it crashes the app regardless of any catches Rect invalidateRect = (Rect)inkManager.ProcessPointerUpdate(e.GetCurrentPoint(_inkingArea)); if (invalidateRect.Height != 0 && invalidateRect.Width != 0) { //we don''t know what has been erased so we clear the render //and add back all the ink saved in the ink manager renderer.Clear(); var remainingStrokes = inkManager.GetStrokes(); renderer.AddInk(remainingStrokes); } break; default: break; } } } catch (Exception) { } }

En esta línea:

Rect invalidateRect = (Rect)inkManager.ProcessPointerUpdate(e.GetCurrentPoint(_inkingArea));

Creo que el problema radica en el proceso de agregar trazos al administrador de tinta. Intenté hacer un nuevo trazo e incluso heredar del InkStroke para hacerlo personalizable, pero la clase InkStroke está sellada y no tiene un constructor. Lo único que encontré para copiarlo fue hacer inkStroke.Clone (). Pero incluso eso tiene sus problemas cuando intenta volver a dibujar la tinta eliminada (deshacer un trazo eliminado).

Traté de hacer esta pregunta lo más clara posible usando la menor cantidad de código para evitar confusiones, así que avíseme si es insuficiente.

También en esta pregunta me estoy enfocando en deshacer una acción de sorteo. Deshacer una acción de borrado (o incluso "borrar todo") tiene su propio conjunto de problemas porque no puedo hacer una copia del objeto InkStroke.

Gracias de antemano por su tiempo y consideración.


Vea este hilo de MSDN, podría ser útil.