using System; using System.Collections.Generic; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Threading; using Brush = System.Windows.Media.Brush; using Color = System.Windows.Media.Color; using Point = System.Windows.Point; namespace WpfSketch { /// /// Window1.xaml 的交互逻辑 /// public partial class Window1 : Window { public delegate void ImageSaveEventHandler(BitmapSource image); public ImageSaveEventHandler ImageSaveEvent; private ColorPicker DefaultColorPicker; public string ImageFile { get; set; } /// /// 目标图片 /// public BitmapSource DestImage { get; set; } = null; private static Mutex mutex = new Mutex(true, "alldream-WpfSketch"); public Window1() { _history = new Stack(); _redoHistory = new Stack(); InitializeComponent(); //ImageFile = "C:\\temp\\out-m.png"; DefaultColorPicker = new ColorPicker(); //SetColor(DefaultColorPicker); _selectedColor = DefaultColorPicker; SetEnable(false, _mode); SetTopMost(true); SetBrushSize(_brushSizes[_brushIndex]); //ExtraToolPanel.Opacity = 0; btnFontIncrease.Visibility = Visibility.Hidden; btnFontDecrease.Visibility = Visibility.Hidden; MainInkCanvas.Strokes.StrokesChanged += StrokesChanged; //MainInkCanvas.AddHandler(InkCanvas.MouseLeftButtonDownEvent, new MouseButtonEventHandler(MainInkCanvas_MouseLeftButtonDown), true); //MainInkCanvas.MouseLeftButtonDown += MainInkCanvas_MouseLeftButtonDown; MainInkCanvas.PreviewMouseLeftButtonDown += MainInkCanvas_MouseLeftButtonDown; MainInkCanvas.MouseLeftButtonUp += MainInkCanvas_MouseLeftButtonUp; MainInkCanvas.MouseRightButtonUp += MainInkCanvas_MouseRightButtonUp; MainInkCanvas.MouseMove += MainInkCanvas_MouseMove; _drawerTextBox.IsHitTestVisible = true; _drawerTextBox.FontSize = 24.0; //_drawerTextBox.Background = Application.Current.Resources["TrueTransparent"] as Brush; _drawerTextBox.Background = Brushes.Transparent;// _drawerTextBox.AcceptsReturn = true; _drawerTextBox.TextWrapping = TextWrapping.Wrap; _drawerTextBox.LostFocus += _drawerTextBox_LostFocus; } public Window1(BitmapSource destImage) : this() { this.DestImage = destImage; } #region /---------Setter---------/ private ColorPicker _selectedColor; private bool _inkVisibility = true; private bool _displayExtraToolPanel = false; private bool _enable = false; private readonly int[] _brushSizes = { 4, 6, 8, 10, 14 }; private int _brushIndex = 0; private bool _displayOrientation; private DrawMode _mode = DrawMode.Pen; private void SetEnable(bool enable, DrawMode mode) { _enable = enable; _mode = mode; InkCanvasEditingMode editingMode = InkCanvasEditingMode.Ink; bool bUseCustomCursor = true; switch (_mode) { case DrawMode.Select: bUseCustomCursor = false; editingMode = InkCanvasEditingMode.Select; break; case DrawMode.Pen: editingMode = InkCanvasEditingMode.Ink; break; case DrawMode.Text: editingMode = InkCanvasEditingMode.None; break; case DrawMode.Line: editingMode = InkCanvasEditingMode.None; break; case DrawMode.Arrow: editingMode = InkCanvasEditingMode.None; break; case DrawMode.Rectangle: editingMode = InkCanvasEditingMode.None; break; case DrawMode.Circle: editingMode = InkCanvasEditingMode.None; break; case DrawMode.Ray: editingMode = InkCanvasEditingMode.None; break; case DrawMode.Erase: bUseCustomCursor = false; editingMode = InkCanvasEditingMode.EraseByStroke; break; case DrawMode.None: _mode = DrawMode.None; break; default: _mode = DrawMode.Select; break; } if (_mode == DrawMode.Ray) { MainInkCanvas.Cursor = new Cursor(new MemoryStream(WpfSketch.Properties.Resources.激光)); } else { MainInkCanvas.Cursor = Cursors.Cross; } if (_mode == DrawMode.Text) { btnFontIncrease.Visibility = Visibility.Visible; btnFontDecrease.Visibility = Visibility.Visible; } else { btnFontIncrease.Visibility = Visibility.Hidden; btnFontDecrease.Visibility = Visibility.Hidden; } MainInkCanvas.UseCustomCursor = bUseCustomCursor; MainInkCanvas.EditingMode = editingMode; if (!_enable || _mode == DrawMode.None) { MainInkCanvas.EditingMode = InkCanvasEditingMode.None; } btnNone.IsChecked = !enable; //if(_mode == DrawMode.None) //{ // btnNone.IsChecked = true; //} // Background = Application.Current.Resources[enable ? "FakeTransparent" : "TrueTransparent"] as Brush; } //private void SetColor(ColorPicker b) //{ // if (ReferenceEquals(_selectedColor, b)) return; // var solidColorBrush = b.Foreground as SolidColorBrush; // if (solidColorBrush == null) // return; // MainInkCanvas.DefaultDrawingAttributes.Color = solidColorBrush.Color; // b.IsActived = true; // if (_selectedColor != null) // _selectedColor.IsActived = false; // _selectedColor = b; // _drawerTextBox.Foreground = solidColorBrush; //} private void SetForeColor(Color color) { if(_selectedColor == null) { return; } var solidColorBrush = _selectedColor.Foreground as SolidColorBrush; solidColorBrush.Color = color; MainInkCanvas.DefaultDrawingAttributes.FitToCurve = true; MainInkCanvas.DefaultDrawingAttributes.IgnorePressure = false; MainInkCanvas.DefaultDrawingAttributes.IsHighlighter = false; MainInkCanvas.DefaultDrawingAttributes.StylusTip = StylusTip.Ellipse; MainInkCanvas.DefaultDrawingAttributes.Color = solidColorBrush.Color; _drawerTextBox.Foreground = solidColorBrush; } private void SetBrushSize(double s) { MainInkCanvas.DefaultDrawingAttributes.Height = s; MainInkCanvas.DefaultDrawingAttributes.Width = s; } private void SetOrientation(bool v) { //PaletteRotate.BeginAnimation(RotateTransform.AngleProperty, new DoubleAnimation(v ? -90 : 0, Duration4)); //Palette.BeginAnimation(MinWidthProperty, new DoubleAnimation(v ? 90 : 0, Duration7)); _displayOrientation = v; } private void SetTopMost(bool v) { //PinButton.IsActived = v; Topmost = v; } #endregion #region Shape Drawer private Point _drawerIntPos; private bool _drawerIsMove = false; private Stroke _drawerLastStroke; private TextBox _drawerTextBox = new TextBox(); private void _drawerTextBox_LostFocus(object sender, RoutedEventArgs e) { String text = _drawerTextBox.Text; if (text.Length > 0) { var textBlock = new TextBlock(); //textBlock.TextWrapping = TextWrapping.NoWrap; textBlock.Text = text; MainInkCanvas.Children.Add(textBlock); textBlock.Visibility = Visibility.Visible; textBlock.Foreground = _drawerTextBox.Foreground; textBlock.FontSize = _drawerTextBox.FontSize; textBlock.TextWrapping = _drawerTextBox.TextWrapping; InkCanvas.SetLeft(textBlock, InkCanvas.GetLeft(_drawerTextBox)); InkCanvas.SetTop(textBlock, InkCanvas.GetTop(_drawerTextBox)); textBlock.Width = _drawerTextBox.Width; textBlock.Height = _drawerTextBox.Height; } MainInkCanvas.Children.Remove(_drawerTextBox); //throw new NotImplementedException(); } private void MainInkCanvas_MouseRightButtonUp(object sender, MouseButtonEventArgs e) { SetEnable(false, _mode); } private void MainInkCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (_enable == false || _mode == DrawMode.Select || _mode == DrawMode.Pen || _mode == DrawMode.None || e.LeftButton != MouseButtonState.Pressed) { return; } if (MainInkCanvas.Children.Contains(_drawerTextBox)) { return; } _ignoreStrokesChange = true; _drawerIsMove = true; _drawerIntPos = e.GetPosition(MainInkCanvas); _drawerLastStroke = null; if (_mode == DrawMode.Text) { _drawerTextBox.Text = ""; if (MainInkCanvas.Children.Contains(_drawerTextBox) == false) MainInkCanvas.Children.Add(_drawerTextBox); _drawerTextBox.Visibility = Visibility.Visible; InkCanvas.SetLeft(_drawerTextBox, _drawerIntPos.X); InkCanvas.SetTop(_drawerTextBox, _drawerIntPos.Y); _drawerTextBox.Width = 0; _drawerTextBox.Height = 0; } } private void MainInkCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (_drawerIsMove == true) { Point endP = e.GetPosition(MainInkCanvas); if (_drawerLastStroke != null && _mode != DrawMode.Ray && _mode != DrawMode.Text) { StrokeCollection collection = new StrokeCollection(); collection.Add(_drawerLastStroke); Push(_history, new StrokesHistoryNode(collection, StrokesHistoryNodeType.Added)); } if (_drawerLastStroke != null && (_mode == DrawMode.Ray || _mode == DrawMode.Text)) { //us animation? /* var ani = new DoubleAnimation(1, 1, Duration4); ani.Completed += (obj,arg)=> { MainInkCanvas.Strokes.Remove(_drawerLastStroke); }; MainInkCanvas.BeginAnimation(OpacityProperty, ani); */ MainInkCanvas.Strokes.Remove(_drawerLastStroke); } if (_mode == DrawMode.Text) { // resize drawer text box _drawerTextBox.Width = Math.Abs(endP.X - _drawerIntPos.X); _drawerTextBox.Height = Math.Abs(endP.Y - _drawerIntPos.Y); if (_drawerTextBox.Width <= 100 || _drawerTextBox.Height <= 40) { _drawerTextBox.Width = 100; _drawerTextBox.Height = 40; } InkCanvas.SetLeft(_drawerTextBox, Math.Min(_drawerIntPos.X, endP.X)); InkCanvas.SetTop(_drawerTextBox, Math.Min(_drawerIntPos.Y, endP.Y)); _drawerTextBox.Focus(); } _drawerIsMove = false; _ignoreStrokesChange = false; } else { if (_mode != DrawMode.Select) { if (_mode == DrawMode.None) { SetEnable(false, _mode); } else { DrawMode mode = _mode; SetEnable(true, DrawMode.None); SetEnable(true, mode); } } //else //{ // //SetEnable(true, _mode); // //_enable = true; //} } } private void MainInkCanvas_MouseMove(object sender, MouseEventArgs e) { if (_drawerIsMove == false) return; DrawingAttributes drawingAttributes = MainInkCanvas.DefaultDrawingAttributes.Clone(); Stroke stroke = null; drawingAttributes.StylusTip = StylusTip.Ellipse; drawingAttributes.IgnorePressure = true; Point endP = e.GetPosition(MainInkCanvas); if (_mode == DrawMode.Text) { List pointList = new List { new Point(_drawerIntPos.X, _drawerIntPos.Y), new Point(_drawerIntPos.X, endP.Y), new Point(endP.X, endP.Y), new Point(endP.X, _drawerIntPos.Y), new Point(_drawerIntPos.X, _drawerIntPos.Y), }; drawingAttributes.Width = 2; drawingAttributes.Height = 2; drawingAttributes.FitToCurve = false;//must be false,other wise rectangle can not be drawed correct StylusPointCollection point = new StylusPointCollection(pointList); stroke = new Stroke(point) { DrawingAttributes = drawingAttributes, }; } else if (_mode == DrawMode.Ray) { //high lighter is ray line drawingAttributes.IsHighlighter = true; List pointList = new List { new Point(_drawerIntPos.X, _drawerIntPos.Y), new Point(endP.X, endP.Y), }; StylusPointCollection point = new StylusPointCollection(pointList); stroke = new Stroke(point) { DrawingAttributes = drawingAttributes, }; } else if (_mode == DrawMode.Line) { List pointList = new List { new Point(_drawerIntPos.X, _drawerIntPos.Y), new Point(endP.X, endP.Y), }; StylusPointCollection point = new StylusPointCollection(pointList); stroke = new Stroke(point) { DrawingAttributes = drawingAttributes, }; } else if (_mode == DrawMode.Arrow) { double w = 15, h = 15; double theta = Math.Atan2(_drawerIntPos.Y - endP.Y, _drawerIntPos.X - endP.X); double sint = Math.Sin(theta); double cost = Math.Cos(theta); List pointList = new List { new Point(_drawerIntPos.X, _drawerIntPos.Y), new Point(endP.X , endP.Y), new Point(endP.X + (w*cost - h*sint), endP.Y + (w*sint + h*cost)), new Point(endP.X,endP.Y), new Point(endP.X + (w*cost + h*sint), endP.Y - (h*cost - w*sint)), }; StylusPointCollection point = new StylusPointCollection(pointList); drawingAttributes.FitToCurve = false;//must be false,other wise rectangle can not be drawed correct stroke = new Stroke(point) { DrawingAttributes = drawingAttributes, }; } else if (_mode == DrawMode.Rectangle) { List pointList = new List { new Point(_drawerIntPos.X, _drawerIntPos.Y), new Point(_drawerIntPos.X, endP.Y), new Point(endP.X, endP.Y), new Point(endP.X, _drawerIntPos.Y), new Point(_drawerIntPos.X, _drawerIntPos.Y), }; drawingAttributes.FitToCurve = false;//must be false,other wise rectangle can not be drawed correct StylusPointCollection point = new StylusPointCollection(pointList); stroke = new Stroke(point) { DrawingAttributes = drawingAttributes, }; } else if (_mode == DrawMode.Circle) { List pointList = GenerateEclipseGeometry(_drawerIntPos, endP); StylusPointCollection point = new StylusPointCollection(pointList); stroke = new Stroke(point) { DrawingAttributes = drawingAttributes }; } if (_drawerLastStroke != null) MainInkCanvas.Strokes.Remove(_drawerLastStroke); if (stroke != null) MainInkCanvas.Strokes.Add(stroke); _drawerLastStroke = stroke; } #endregion #region /---------Generator---------/ private static string GenerateFileName(string fileExt = ".fdw") { return DateTime.Now.ToString("yyyyMMdd-HHmmss") + fileExt; } private List GenerateEclipseGeometry(Point st, Point ed) { double a = 0.5 * (ed.X - st.X); double b = 0.5 * (ed.Y - st.Y); List pointList = new List(); for (double r = 0; r <= 2 * Math.PI; r = r + 0.01) { pointList.Add(new Point(0.5 * (st.X + ed.X) + a * Math.Cos(r), 0.5 * (st.Y + ed.Y) + b * Math.Sin(r))); } return pointList; } #endregion #region /---------IO---------/ private StrokeCollection _preLoadStrokes = null; private void QuickSave(string filename = "QuickSave_") { //Save(new FileStream("Save\\" + filename + GenerateFileName(), FileMode.OpenOrCreate)); if(this.DestImage != null) { Save2Image(); } else { Save(null); } } private void Save2Image() { try { //string strFile = "C:\\temp\\rend.png"; double width = MainInkCanvas.ActualWidth; double height = MainInkCanvas.ActualHeight; RenderTargetBitmap bmpCopied = new RenderTargetBitmap((int)Math.Round(width) , (int)Math.Round(height), 96, 96, PixelFormats.Default); DrawingVisual dv = new DrawingVisual(); using (DrawingContext dc = dv.RenderOpen()) { VisualBrush vb = new VisualBrush(MainInkCanvas); dc.DrawImage(this.img.Source, new Rect(new System.Windows.Point(), new System.Windows.Size(width, height))); dc.DrawRectangle(vb, null, new Rect(new System.Windows.Point(), new System.Windows.Size(width, height))); } bmpCopied.Render(dv); this.DestImage = bmpCopied; _saved = true; ImageSaveEvent?.Invoke(this.DestImage); } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void Save(Stream fs) { try { //string strFile = "C:\\temp\\rend.png"; double width = MainInkCanvas.ActualWidth; double height = MainInkCanvas.ActualHeight; RenderTargetBitmap bmpCopied = new RenderTargetBitmap((int)Math.Round(width) , (int)Math.Round(height), 96, 96, PixelFormats.Default); DrawingVisual dv = new DrawingVisual(); using (DrawingContext dc = dv.RenderOpen()) { VisualBrush vb = new VisualBrush(MainInkCanvas); dc.DrawImage(this.img.Source, new Rect(new System.Windows.Point(), new System.Windows.Size(width, height))); dc.DrawRectangle(vb, null, new Rect(new System.Windows.Point(), new System.Windows.Size(width, height))); } bmpCopied.Render(dv); using (FileStream file = new FileStream(ImageFile, FileMode.Create, FileAccess.Write)) { PngBitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(bmpCopied)); encoder.Save(file); _saved = true; } } catch(Exception ex) { MessageBox.Show(ex.Message); } //try //{ // if (fs == Stream.Null) return; // MainInkCanvas.Strokes.Save(fs); // _saved = true; // Display("画板保存成功"); // fs.Close(); //} //catch (Exception ex) //{ // MessageBox.Show(ex.ToString()); // Display("画板保存失败"); //} } private StrokeCollection Load(Stream fs) { try { return new StrokeCollection(fs); } catch (Exception ex) { MessageBox.Show(ex.ToString()); Display("画板加载失败"); } return new StrokeCollection(); } private void AnimatedReload(StrokeCollection sc) { _preLoadStrokes = sc; //var ani = new DoubleAnimation(0, Duration3); //ani.Completed += LoadAniCompleted; //MainInkCanvas.BeginAnimation(OpacityProperty, ani); } private void LoadAniCompleted(object sender, EventArgs e) { if (_preLoadStrokes == null) return; MainInkCanvas.Strokes = _preLoadStrokes; //Display("画板加载完成"); _saved = true; ClearHistory(); //MainInkCanvas.BeginAnimation(OpacityProperty, new DoubleAnimation(1, Duration3)); } private static string[] GetSavePathList() { return Directory.GetFiles("Save", "*.fdw"); } private static string GetFileNameFromPath(string path) { return System.IO.Path.GetFileName(path); } #endregion #region /---------Helper---------/ private string _staticInfo = ""; private bool _displayingInfo; private async void Display(string info) { //InfoBox.Text = info; _displayingInfo = true; //await InfoDisplayTimeUp(new Progress(box => InfoBox.Text = box)); } private Task InfoDisplayTimeUp(IProgress box) { return Task.Run(() => { Task.Delay(2000).Wait(); box.Report(_staticInfo); _displayingInfo = false; }); } private void SetStaticInfo(string info) { _staticInfo = info; //if (!_displayingInfo) // InfoBox.Text = _staticInfo; } private static Stream SaveDialog(string initFileName, string fileExt = ".fdw", string filter = "Free Draw Save (*.fdw)|*fdw") { var dialog = new Microsoft.Win32.SaveFileDialog() { DefaultExt = fileExt, Filter = filter, FileName = initFileName, InitialDirectory = Directory.GetCurrentDirectory() + "Save" }; return dialog.ShowDialog() == true ? dialog.OpenFile() : Stream.Null; } private static Stream OpenDialog(string fileExt = ".fdw", string filter = "Free Draw Save (*.fdw)|*fdw") { var dialog = new Microsoft.Win32.OpenFileDialog() { DefaultExt = fileExt, Filter = filter, }; return dialog.ShowDialog() == true ? dialog.OpenFile() : Stream.Null; } #endregion #region /---------Judge--------/ private bool _saved = false; private bool IsUnsaved() { return MainInkCanvas.Strokes.Count != 0 && !_saved; } private bool PromptToSave() { if (!IsUnsaved()) return true; var r = MessageBox.Show("You have unsaved work, do you want to save it now?", "Unsaved data", MessageBoxButton.YesNoCancel); if (r == MessageBoxResult.Yes || r == MessageBoxResult.OK) { QuickSave(); return true; } if (r == MessageBoxResult.No || r == MessageBoxResult.None) return true; return false; } #endregion private void Window_Loaded(object sender, RoutedEventArgs e) { FixupToolBarOverflowArrow(tbDraw); if(this.DestImage != null) { MainInkCanvas.Width = this.DestImage.Width; MainInkCanvas.Height = this.DestImage.Height; img.Source = this.DestImage; } else if (!string.IsNullOrEmpty(ImageFile)) { MemoryStream ms = null; using (var stream = File.Open(ImageFile, FileMode.Open)) { using (var reader = new BinaryReader(stream)) { byte[] datas = reader.ReadBytes((int)stream.Length); ms = new MemoryStream(datas); } } BitmapImage imgSource = new BitmapImage(); imgSource.BeginInit(); imgSource.StreamSource = ms; imgSource.EndInit(); MainInkCanvas.Width = imgSource.Width; MainInkCanvas.Height = imgSource.Height; img.Source = imgSource; } else { MainInkCanvas.Width = 500; MainInkCanvas.Height = 400; } // 默认红色画笔 this.btnColorRed.IsChecked = true; this.btnColorRed.RaiseEvent(new RoutedEventArgs(RadioButton.ClickEvent)); this.rbtnPenWidthMin.IsChecked = true; // 默认绘图圆 this.btnCircle.IsChecked = true; this.btnCircle.RaiseEvent(new RoutedEventArgs(RadioButton.ClickEvent)); } private static void FixupToolBarOverflowArrow(ToolBar toolBar) { Action fixup = () => { var overflowButton = toolBar.Template.FindName("OverflowButton", toolBar) as System.Windows.Controls.Primitives.ButtonBase; if (overflowButton != null) { overflowButton.SetBinding( VisibilityProperty, new Binding("IsEnabled") { RelativeSource = RelativeSource.Self, Converter = new BooleanToVisibilityConverter() }); } }; if (toolBar.IsLoaded) { fixup(); } else { RoutedEventHandler handler = null; handler = (sender, e) => { fixup(); toolBar.Loaded -= handler; }; toolBar.Loaded += handler; } } /// /// 选择颜色. /// /// The sender. /// The e. private void ColorButton_Click(object sender, RoutedEventArgs e) { //要获得所选方块的颜色,需要将SolidColorBrush取Color //_selectedColor.Foreground = (SolidColorBrush)((Rectangle)(sender as RadioButton).Content).Fill; Color color = ((SolidColorBrush)((Rectangle)(sender as RadioButton).Content).Fill).Color; this.SetForeColor(color); } #region /---------Ink---------/ private readonly Stack _history; private readonly Stack _redoHistory; private bool _ignoreStrokesChange; private void Undo() { if (!CanUndo()) return; var last = Pop(_history); _ignoreStrokesChange = true; if (last.Type == StrokesHistoryNodeType.Added) MainInkCanvas.Strokes.Remove(last.Strokes); else MainInkCanvas.Strokes.Add(last.Strokes); _ignoreStrokesChange = false; Push(_redoHistory, last); } private void Redo() { if (!CanRedo()) return; var last = Pop(_redoHistory); _ignoreStrokesChange = true; if (last.Type == StrokesHistoryNodeType.Removed) MainInkCanvas.Strokes.Remove(last.Strokes); else MainInkCanvas.Strokes.Add(last.Strokes); _ignoreStrokesChange = false; Push(_history, last); } private static void Push(Stack collection, StrokesHistoryNode node) { collection.Push(node); } private static StrokesHistoryNode Pop(Stack collection) { return collection.Count == 0 ? null : collection.Pop(); } private bool CanUndo() { return _history.Count != 0; } private bool CanRedo() { return _redoHistory.Count != 0; } private void StrokesChanged(object sender, StrokeCollectionChangedEventArgs e) { if (_ignoreStrokesChange) return; _saved = false; if (e.Added.Count != 0) Push(_history, new StrokesHistoryNode(e.Added, StrokesHistoryNodeType.Added)); if (e.Removed.Count != 0) Push(_history, new StrokesHistoryNode(e.Removed, StrokesHistoryNodeType.Removed)); ClearHistory(_redoHistory); } private void ClearHistory() { ClearHistory(_history); ClearHistory(_redoHistory); } private static void ClearHistory(Stack collection) { collection?.Clear(); } private void Clear() { MainInkCanvas.Children.Clear(); MainInkCanvas.Strokes.Clear(); ClearHistory(); } private void AnimatedClear() { //no need any more //var ani = new DoubleAnimation(0, Duration3); //ani.Completed += ClearAniComplete; ; //MainInkCanvas.BeginAnimation(OpacityProperty, ani); } private void ClearAniComplete(object sender, EventArgs e) { Clear(); //Display("画板清除完成"); //MainInkCanvas.BeginAnimation(OpacityProperty, new DoubleAnimation(1, Duration3)); } #endregion /// /// 绘制圆. /// /// The source of the event. /// The instance containing the event data. private void BtnCircle_Click(object sender, RoutedEventArgs e) { SetEnable(true, DrawMode.Circle); } /// /// 任意画笔. /// /// The source of the event. /// The instance containing the event data. private void BtnPen_Click(object sender, RoutedEventArgs e) { SetEnable(true, DrawMode.Pen); } /// /// 绘制直线 /// /// /// private void BtnLine_Click(object sender, RoutedEventArgs e) { SetEnable(true, DrawMode.Line); } private void BtnRectangle_Click(object sender, RoutedEventArgs e) { SetEnable(true, DrawMode.Rectangle); } private void BtnText_Click(object sender, RoutedEventArgs e) { SetEnable(true, DrawMode.Text); } private void BtnSelect_Click(object sender, RoutedEventArgs e) { SetEnable(true, DrawMode.Select); } private void BtnArrow_Click(object sender, RoutedEventArgs e) { SetEnable(true, DrawMode.Arrow); } private void BtnNone_Click(object sender, RoutedEventArgs e) { SetEnable(false, DrawMode.None); } private void BtnFontIncrease_Click(object sender, RoutedEventArgs e) { _drawerTextBox.FontSize = _drawerTextBox.FontSize + 2; _drawerTextBox.FontSize = Math.Min(60, _drawerTextBox.FontSize); } private void BtnFontDecrease_Click(object sender, RoutedEventArgs e) { _drawerTextBox.FontSize = _drawerTextBox.FontSize - 2; _drawerTextBox.FontSize = Math.Max(14, _drawerTextBox.FontSize); } /// /// 撤销. /// /// The source of the event. /// The instance containing the event data. private void BtnUndo_Click(object sender, RoutedEventArgs e) { Undo(); } /// /// 重做. /// /// The source of the event. /// The instance containing the event data. private void BtnRedo_Click(object sender, RoutedEventArgs e) { Redo(); } private void PenWidth_Checked(object sender, RoutedEventArgs e) { double dWidth = ((Ellipse)(sender as RadioButton).Content).Width; SetBrushSize(dWidth); } /// /// 保存. /// /// The source of the event. /// The instance containing the event data. private void BtnSave_Click(object sender, RoutedEventArgs e) { if (MainInkCanvas.Strokes.Count == 0) { Display("没有笔迹要保存"); return; } QuickSave(); this.Close(); } /// /// 退出. /// /// The source of the event. /// The instance containing the event data. private void BtnExit_Click(object sender, RoutedEventArgs e) { this.Close(); } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if (IsUnsaved()) { if (MessageBox.Show(this, "尚未保存,是否退出?", "退出" , MessageBoxButton.YesNo, MessageBoxImage.Question , MessageBoxResult.No) == MessageBoxResult.Yes) { //Application.Current.Shutdown(); //MessageBox.Show("退出"); return; } else { e.Cancel = true; } } } } }