C# WPF自制批注工具(方便标记重点和演示)

   在教学和演示中,我们通常需要对重点进行批注,下载安装第三方工具批注显得很麻烦。本篇使用WPF开发了一个批注工具,工具小巧,功能丰富,非常使用日常免费使用,或者进行再次开发。

自制批注工具具有以下功能特点:

  • 支持图画,擦除,撤销,恢复,改变画板颜色功能
  • 提供颜色选择和线条大小设置功能
  • 方便演示教学

示例代码如下:

        Stack<StrokeCollection> undoStack = new Stack<StrokeCollection>();//撤销Stack<StrokeCollection> recoverStack = new Stack<StrokeCollection>();//恢复撤销public MainWindow(){InitializeComponent();try{EraserCanvas.MouseDown += EraserCanvas_MouseDown;EraserCanvas.MouseMove += EraserCanvas_MouseMove;EraserCanvas.MouseUp += EraserCanvas_MouseUp;Global.Instance.CurrentCanvas.PreviewMouseDown += WriteBorad_PreviewMouseDown;InkCanvasRootPanel.Children.Clear();InkCanvasRootPanel.Children.Add(Global.Instance.CurrentCanvas);}catch (Exception){}}private void Window_Loaded(object sender, RoutedEventArgs e){//设置色板和清空橡皮位置Window window = Window.GetWindow(rdoPen);Point point = rdoPen.TransformToAncestor(window).Transform(new Point(0, 0));translateColor.X = translateColor.X - 100;translateEraser.X = translateEraser.X-30;if (rdoPenWidthMin.Content.ToString() == Global.Instance.ColorHelper.selectedPenWidth.Trim())rdoPenWidthMin.IsChecked = true;else if (rdoPenWidthMedium.Content.ToString() == Global.Instance.ColorHelper.selectedPenWidth.Trim())rdoPenWidthMedium.IsChecked = true;else if (rdoPenWidthMax.Content.ToString() == Global.Instance.ColorHelper.selectedPenWidth.Trim())rdoPenWidthMax.IsChecked = true;//初始化色板foreach (string color in Global.Instance.ColorHelper.colorList){RadioButton btntemp = new RadioButton();btntemp.SetResourceReference(StyleProperty, "ColorSelectStyle");btntemp.Width = 30;btntemp.Height = 30;btntemp.Margin = new Thickness(2, 2, 2, 0);btntemp.Background = new SolidColorBrush((System.Windows.Media.Color)ColorConverter.ConvertFromString(color));if (btntemp.Background.ToString() == Global.Instance.ColorHelper.selectedColor){btntemp.IsChecked = true;Global.Instance.CurrentCanvas.DefaultDrawingAttributes.Color =(System.Windows.Media.Color)ColorConverter.ConvertFromString((string)Global.Instance.ColorHelper.selectedColor);}                    uniformColor.Children.Add(btntemp);}}#region InkCanvas操作bool transformColorFlag = false;bool transformEraserClearFlag = false;private void RadioButton_Click(object sender, RoutedEventArgs e){//橡皮模式下选择其他工具关闭橡皮擦功能EraserCanvas.Visibility = Visibility.Collapsed;_eraserisDown = false;//如果色板打开下选择其他工具,隐藏色板工具if (!(bool)rdoPen.IsChecked){transformColorFlag = false;translateColor.Y = 300;}if (!(bool)rdoEraser.IsChecked){transformEraserClearFlag = false;translateEraser.Y = 100;}if ((sender as RadioButton).Content.ToString() == "画笔"){//Topmost = false;this.Background = (Brush)new BrushConverter().ConvertFromString("#01000000");if (transformColorFlag){translateColor.Y = -10;}else{translateColor.Y = 300;}transformColorFlag = !transformColorFlag;Global.Instance.CurrentCanvas.EditingMode = InkCanvasEditingMode.Ink;}else if ((sender as RadioButton).Content.ToString() == "橡皮"){this.Background = (Brush)new BrushConverter().ConvertFromString("#01000000");if (transformEraserClearFlag){translateEraser.Y = -10;}else{translateEraser.Y = 100;}transformEraserClearFlag = !transformEraserClearFlag;Global.Instance.CurrentCanvas.EditingMode = InkCanvasEditingMode.None;EraserCanvas.Visibility = Visibility.Visible;TranslateTransform.X = -1000;TranslateTransform.Y = -1000;}else if ((sender as RadioButton).Content.ToString() == "选择"){//Topmost = true;this.Background = System.Windows.Media.Brushes.Transparent;Global.Instance.CurrentCanvas.EditingMode = InkCanvasEditingMode.None;// Global.Instance.CurrentCanvas.EditingMode = InkCanvasEditingMode.Select;}else if ((sender as RadioButton).Content.ToString() == "撤销"){if (undoStack.Count > 0){recoverStack.Push(Global.Instance.CurrentCanvas.Strokes.Clone());Global.Instance.CurrentCanvas.Strokes = undoStack.Pop();}}else if ((sender as RadioButton).Content.ToString() == "恢复"){if (recoverStack.Count > 0){undoStack.Push( Global.Instance.CurrentCanvas.Strokes.Clone());Global.Instance.CurrentCanvas.Strokes = recoverStack.Pop();}}}#endregion

实例链接:https://download.csdn.net/download/lvxingzhe3/89505204

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/39605.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AUTOSAR NvM模块(五)

NvMRbCallbackSignatureAR45 改变回调函数的参数类型。 TRUE&#xff1a;根据AR44及之后版本&#xff0c;回调函数使用NvM_<Multi;Init>BlockRequestType参数类型。详细的函数调用参数请参考回调参数。 FALSE&#xff1a;根据AR43及之前版本&#xff0c;回调函数使用S…

GPT-5 一年半后发布,对此你有何期待?

CHATGPT5&#xff1a;未来一年内的期待与挑战 随着人工智能技术的飞速发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域的突破不断涌现。在这一背景下&#xff0c;CHATGPT系列模型作为NLP领域的佼佼者&#xff0c;其每一次的更新都牵动着业界的目光。当得知CHATG…

Spring Boot中泛型参数的灵活运用:最佳实践与性能优化

泛型是Java中一种强大的特性&#xff0c;它提供了编写通用代码的能力&#xff0c;使得代码更加灵活和可复用。在Spring Boot应用程序中&#xff0c;泛型参数的灵活运用可以带来诸多好处&#xff0c;包括增强代码的可读性、提高系统的健壮性以及优化系统的性能。本文将深入探讨在…

Flask 数据创建时出错

当我们在使用 Flask 创建数据时遇到错误&#xff0c;可能有多种原因&#xff0c;包括代码错误、数据库配置问题或依赖项错误。具体情况我会总结成一篇文章记录下&#xff0c;主要是归类总结一些常见的解决方法和调试步骤&#xff0c;帮助大家解决问题&#xff1a; 1、问题背景 …

2024.7.2 随笔 控制内心的焦虑

文章目录 前言2024.7.2 随笔 控制内心的焦虑人生的新阶段冒名顶替综合征年龄焦虑、职业焦虑未来的计划 前言 我已经记不清楚&#xff0c;好久没有这样写长篇的博文&#xff0c;或者说是&#xff0c;感悟吧。起因是刷到了一个博主的视频&#xff0c;真的治愈了我的内心&#xf…

OFDM技术概述8——FBMC

Filter bank multicarrier(FBMC&#xff0c;滤波器组多载波)&#xff0c;是一种类似于OFDM的调制方式&#xff0c;用滤波器抑制子载波的旁瓣大小&#xff0c;使用FFT/IFFT或多相滤波器实现&#xff0c;其应用于5G的主要优势&#xff1a; 子载波信号带限&#xff0c;带外泄漏小…

Perl 简介

Perl 简介 Perl 是一种高级、通用、解释型、动态编程语言。由 Larry Wall 于 1987 年首次发布,设计哲学是“易于修改”和“实用”。Perl 的名字源自“Practical Extraction and Reporting Language”,但也可以解释为“Pathologically Eclectic Rubbish Lister”。Perl 被广泛…

LiveNVR监控流媒体Onvif/RTSP用户手册-视频广场:状态记录、播放、回放入口、筛选在线离线、搜索

LiveNVR监控流媒体Onvif/RTSP用户手册-视频广场:状态记录、播放、回放入口、筛选在线离线、搜索 1、视频广场1.1、搜索筛选1.2、状态记录1.3、播放1.4、视频信息1.5、回放入口 2、RTSP/HLS/FLV/RTMP拉流Onvif流媒体服务 1、视频广场 1.1、搜索筛选 可以下拉筛选 在线、离线 &a…

C++部分复习笔记上

C语法复习 1. C入门基础 缺省参数 半缺省参数必须从右往左依次来给出&#xff0c;不能间隔着给缺省参数不能在函数声明和定义中同时出现缺省值必须是常量或者全局变量C语言不支持&#xff08;编译器不支持&#xff09; 函数重载 函数重载是函数的一种特殊情况&#xff0c;…

前端跨域问题--解析与实战

引言 在现代网络应用中&#xff0c;跨域问题是一个常见的挑战。由于浏览器的同源策略&#xff0c;限制了从不同源&#xff08;域名、协议或端口&#xff09;进行资源共享&#xff0c;这就造成了跨域访问的限制。跨域资源共享&#xff08;CORS&#xff09;是一种技术&#xff0…

如何无线连接ios,自动化稳定

如果你的iPhone的USB端口无法使用&#xff0c;但你需要进行自动化测试或其他操作&#xff0c;可以通过无线连接来实现。无线连接通常涉及到使用Wi-Fi网络&#xff0c;这样你就可以在不使用USB线的情况下与设备交互。以下是一些可以考虑的方法&#xff1a; 1.使用Xcode进行无线…

William Yang:从区块链先锋到艺术平台创始人

在区块链技术和加密货币市场飞速发展的今天&#xff0c;William Yang无疑是这一领域的佼佼者。他不仅在学术和媒体领域取得了显著成就&#xff0c;更在创业之路上不断探索&#xff0c;成为了业内知名的KOL&#xff08;关键意见领袖&#xff09;。今天&#xff0c;我们有幸采访到…

AI姓氏头像生成微信小程序系统源码

&#x1f525;【科技新潮流】AI姓氏头像生成系统&#xff0c;你的专属个性新名片&#xff01;&#x1f389; &#x1f31f; 开篇惊艳&#xff1a;一键解锁你的姓氏魅力 ✨ Hey小伙伴们&#xff0c;今天我要安利一个超酷炫的科技小玩意——AI姓氏头像生成系统&#xff01;是不…

js字符串序列化为二进制数据

在JavaScript中&#xff0c;可以通过不同的方式将字符串序列化为二进制数据。以下是几种常见的方法&#xff1a; TextEncoder 和 TextDecoder JavaScript 提供了 TextEncoder 和 TextDecoder 对象&#xff0c;可以用来处理字符串和二进制数据之间的转换。 // 将字符串转换为二进…

MySQL Server时区支持

本文介绍MySQL维护的时区设置——如何加载命名时间支持所需的系统表&#xff0c;如何及时了解时区变化&#xff0c;以及如何启用闰秒支持。 从MySQL 8.0.19开始&#xff0c;插入的日期时间值也支持时区偏移。 1 时区变量 MySQL Server维护了几个时区设置&#xff1a; 服务器…

爬虫笔记20——票星球抢票脚本的实现

以下内容仅供交流学习使用&#xff01;&#xff01;&#xff01; 思路分析 前面的爬虫笔记一步一步走过来我们的技术水平也有了较大的提升了&#xff0c;现在我们来进行一下票星球抢票实战项目&#xff0c;实现票星球的自动抢票。 我们打开票星球的移动端页面&#xff0c;分…

视频字幕提取在线工具有哪些?总结5个字幕提取工具

平时在沉浸式追剧的时候&#xff0c;我们常常都会被影视剧中的各种金句爆梗而逗得开怀大笑~而真正要用到时候却总是一片头脑空白。其实要记住它们最好的办法便是将其提取留档下来&#xff0c;每次有需要的时候打开就能一下子回顾到~ 今天就来带大家盘一盘视频字幕提取的软件好…

高考假期预习指南

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

目标检测YOLO实战应用案例100讲-基于深度学习的无人机影像小目标识别

目录 前言 研究现状 深度学习研究现状 目标检测研究现状 目标检测存在的问题 2 基于深度学习的目标检测算法理论基础 2.1 卷积神经网络 2.1.1 卷积层 2.1.2 池化层 2.1.3 激活函数 2.1.4 全连接层 2.2 优化器 2.3 基于深度学习的目标检测算法 2.3.1 …

树上差分的公式推导

今天写了一道题目&#xff0c;需要采用线段树合并树上差分来解决 题目链接&#xff1a;P1600 [NOIP2016 提高组] 天天爱跑步 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 其实当时已经想到要用这两种方法&#xff0c;但苦于一直找不到转移方程&#xff0c;最后看了答案才领…