using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; namespace Common.system { internal enum ZPenType : byte { Pen = 1, Erase = 2 }; internal class ZBBPage { public List lines { get; set; } public List lines_histoty { get; set; } public ZBBPage() { lines = new List(); lines_histoty = new List(); } } internal class ZBBPageStep { public StrokeCollection lines_curr { get; set; } public StrokeCollection lines_add { get; set; } public StrokeCollection lines_remove { get; set; } public ZBBPageStep() { lines_curr = new StrokeCollection(); lines_add = new StrokeCollection(); lines_remove = new StrokeCollection(); } } public class BlackboardNew { private InkCanvas m_canvas; //private ZPenType type = ZPenType.Pen; private int pagenum = 0; private readonly int erasesize = 64; private readonly int pensize = 3; private int undoOrRedo = 0; //是否在进行撤销恢复操作 private Color pencolor; private readonly List strokes_page_all = new List(); // 添加这个变量是因为在用橡皮擦时 一次操作会触发多次StrokesChanged回掉 这里是把多次回掉合并在一起 private ZBBPageStep step = null; public BlackboardNew(InkCanvas canvas) { init(canvas, Colors.White); } public BlackboardNew(InkCanvas canvas, Color _pencolor) { init(canvas, _pencolor); } private void init(InkCanvas canvas, Color _pencolor) { m_canvas = canvas; pencolor = _pencolor; ZBBPage page = new ZBBPage(); page.lines.Add(new ZBBPageStep()); strokes_page_all.Add(page); if (canvas != null) { canvas.EditingMode = InkCanvasEditingMode.Ink; DrawingAttributes drawingAttributes = new DrawingAttributes(); canvas.DefaultDrawingAttributes = drawingAttributes; drawingAttributes.Width = pensize; drawingAttributes.Height = pensize; drawingAttributes.Color = pencolor; drawingAttributes.FitToCurve = true; drawingAttributes.IgnorePressure = false; canvas.Strokes.StrokesChanged += Strokes_StrokesChanged; canvas.StrokeCollected += Canvas_StrokeCollected; canvas.StrokeErasing += Canvas_StrokeErasing; canvas.StrokeErased += Canvas_StrokeErased; canvas.MouseUp += Canvas_MouseUp; } } private void Canvas_StrokeErasing(object sender, InkCanvasStrokeErasingEventArgs e) { undoOrRedo = 0; } private void Canvas_StrokeErased(object sender, RoutedEventArgs e) { } private void Canvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e) { } private void Canvas_MouseUp(object sender, MouseButtonEventArgs e) { if (step != null) { ZBBPage page = strokes_page_all[pagenum]; if (page != null) { step.lines_curr.Add(m_canvas.Strokes); page.lines.Add(step); step = null; } } } private void Strokes_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e) { if (undoOrRedo > 0) { undoOrRedo -= 1; return; } if (step == null) { step = new ZBBPageStep(); } // 笔模式 if (e.Added.Count > 0 && e.Removed.Count == 0) { step.lines_add.Add(e.Added); } // 橡皮模式 会多次进入回掉 else if (e.Removed.Count > 0) { step.lines_add.Add(e.Added); for (int i = 0; i < e.Removed.Count; i++) { Stroke removeItem = e.Removed[i]; if (step.lines_add.Contains(removeItem)) { step.lines_add.Remove(removeItem); } else { step.lines_remove.Add(removeItem); } } } } // public方法 笔 public void change_pen() { //this.type = ZPenType.Pen; DrawingAttributes drawingAttributes = new DrawingAttributes(); m_canvas.DefaultDrawingAttributes = drawingAttributes; drawingAttributes.Color = pencolor; drawingAttributes.Width = pensize; drawingAttributes.Height = pensize; drawingAttributes.FitToCurve = true; drawingAttributes.IgnorePressure = false; m_canvas.EditingMode = InkCanvasEditingMode.Ink; } // 橡皮 public void change_erase() { //this.type = ZPenType.Erase; m_canvas.EditingMode = InkCanvasEditingMode.EraseByPoint; m_canvas.EraserShape = new EllipseStylusShape(erasesize, erasesize, 0); } // 撤销 public void undo() { ZBBPage page = strokes_page_all[pagenum]; if (page != null && m_canvas.Strokes.Count > 0 && page.lines.Count > 1) { ZBBPageStep last = page.lines.Last(); page.lines.Remove(last); page.lines_histoty.Add(last); if (page.lines.Last().lines_curr.Count > 0) { undoOrRedo = 2; } else { undoOrRedo = 1; } m_canvas.Strokes.Clear(); m_canvas.Strokes.Add(page.lines.Last().lines_curr); } } // 恢复 public void redo() { ZBBPage page = strokes_page_all[pagenum]; if (page != null && page.lines_histoty.Count > 0) { ZBBPageStep line = page.lines_histoty[page.lines_histoty.Count - 1]; page.lines.Add(line); page.lines_histoty.Remove(line); if (page.lines.Last().lines_curr.Count > 0) { undoOrRedo = 2; } else { undoOrRedo = 1; } m_canvas.Strokes.Clear(); m_canvas.Strokes.Add(page.lines.Last().lines_curr); } } // 清空 public void clear() { ZBBPage page = strokes_page_all[pagenum]; if (page != null) { m_canvas.Strokes.Clear(); page.lines_histoty.Clear(); page.lines.Clear(); page.lines.Add(new ZBBPageStep()); } } public void changepage(int mpagenum) { if (pagenum != mpagenum) { pagenum = mpagenum; if (pagenum >= strokes_page_all.Count) { int numadd = pagenum - strokes_page_all.Count + 1; for (int i = 0; i < numadd; i++) { ZBBPage pagetemp = new ZBBPage(); pagetemp.lines.Add(new ZBBPageStep()); strokes_page_all.Add(pagetemp); } } ZBBPage page = strokes_page_all[pagenum]; if (page != null) { if (page.lines.Last().lines_curr.Count > 0) { undoOrRedo += 1; } if (m_canvas.Strokes.Count > 0) { undoOrRedo += 1; m_canvas.Strokes.Clear(); } m_canvas.Strokes.Add(page.lines.Last().lines_curr); } } } } }