C#/WPF 自制白板工具

news2024/12/28 17:38:16

        随着电子屏幕技术的发展,普通的黑板已不再适用现在的教学和演示环境,电子白板应运而生。本篇使用WPF开发了一个电子白板工具,功能丰富,非常使用日常免费使用,或者进行再次开发。

示例代码如下:

        Stack<StrokeCollection> undoStack = new Stack<StrokeCollection>();//撤销
        Stack<StrokeCollection> recoverStack = new Stack<StrokeCollection>();//恢复撤销
 
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = Global.Instance.WhiteBoardPageModel;
            try
            {
                EraserCanvas.MouseDown += EraserCanvas_MouseDown;
                EraserCanvas.MouseMove += EraserCanvas_MouseMove;
                EraserCanvas.MouseUp += EraserCanvas_MouseUp;


                Global.Instance.InkCanvasList[ Global.Instance.WhiteBoardPageModel.PageIndex-1].PreviewMouseDown += WriteBorad_PreviewMouseDown;
                InkCanvasRootPanel.Children.Clear();
                InkCanvasRootPanel.Children.Add(Global.Instance.InkCanvasList[Global.Instance.WhiteBoardPageModel.PageIndex - 1]);
            }
            catch (Exception)
            {

            }

        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //top = this.Top;
            //left = this.Left;
            //width = this.Width;
            //heigh = this.Height;

            //启动最大化白板
            this.Top = this.Left = 0;
            this.Width = SystemParameters.WorkArea.Width;
            this.Height = SystemParameters.WorkArea.Height;

            //设置色板和清空橡皮位置
            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.InkCanvasList[ Global.Instance.WhiteBoardPageModel.PageIndex-1].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() == "画笔")
            {
                if (transformColorFlag)
                {
                    translateColor.Y = -10;
                }
                else
                {
                    translateColor.Y = 300;
                }
                transformColorFlag = !transformColorFlag;
                Global.Instance.InkCanvasList[Global.Instance.WhiteBoardPageModel.PageIndex - 1].EditingMode = InkCanvasEditingMode.Ink;
            }
            else if ((sender as RadioButton).Content.ToString() == "橡皮")
            {
                if (transformEraserClearFlag)
                {
                    translateEraser.Y = -10;
                }
                else
                {
                    translateEraser.Y = 100;
                }
                transformEraserClearFlag = !transformEraserClearFlag;

                Global.Instance.InkCanvasList[Global.Instance.WhiteBoardPageModel.PageIndex - 1].EditingMode = InkCanvasEditingMode.None;
                EraserCanvas.Visibility = Visibility.Visible;
                TranslateTransform.X = -1000;
                TranslateTransform.Y = -1000;
                //Global.Instance.InkCanvasList[ Global.Instance.WhiteBoardPageModel.PageIndex-1].EditingMode = InkCanvasEditingMode.EraseByPoint;
                //Global.Instance.InkCanvasList[ Global.Instance.WhiteBoardPageModel.PageIndex-1].EditingMode = InkCanvasEditingMode.EraseByStroke;
            }
            else if ((sender as RadioButton).Content.ToString() == "选择")
            {
                //PenFullScreen();
                Global.Instance.InkCanvasList[Global.Instance.WhiteBoardPageModel.PageIndex - 1].EditingMode = InkCanvasEditingMode.None;
                //Global.Instance.InkCanvasList[ Global.Instance.WhiteBoardPageModel.PageIndex-1].EditingMode = InkCanvasEditingMode.Select;
            }
            else if ((sender as RadioButton).Content.ToString() == "撤销")
            {
                if (undoStack.Count > 0)
                {
                    recoverStack.Push(Global.Instance.InkCanvasList[Global.Instance.WhiteBoardPageModel.PageIndex - 1].Strokes.Clone());
                    Global.Instance.InkCanvasList[Global.Instance.WhiteBoardPageModel.PageIndex - 1].Strokes = undoStack.Pop();
                }
            }
            else if ((sender as RadioButton).Content.ToString() == "恢复")
            {
                if (recoverStack.Count > 0)
                {
                    undoStack.Push(Global.Instance.InkCanvasList[Global.Instance.WhiteBoardPageModel.PageIndex - 1].Strokes.Clone());
                    Global.Instance.InkCanvasList[Global.Instance.WhiteBoardPageModel.PageIndex - 1].Strokes = recoverStack.Pop();
                }
            }
        }
        #endregion

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

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

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

相关文章

杨万里,诚斋体的开创者

杨万里&#xff0c;字廷秀&#xff0c;号诚斋&#xff0c;生于南宋绍兴元年&#xff08;公元1127年&#xff09;&#xff0c;卒于南宋庆元二年&#xff08;公元1206年&#xff09;&#xff0c;享年79岁。在中国古代文学的璀璨星河中&#xff0c;南宋诗人杨万里以其清新脱俗、贴…

方案论证项目实现功能

文章目录 1. 场景加载2. 3D 模型2.1. 坐标转换2.2. 放置模型2.3. 调整模型2.4. 提交方案 3. 查看方案3.1. 场景还原3.2. 删除 1. 场景加载 加载Cesium的Melbourne Photogrammetry的倾斜摄影作为底图&#xff0c;本身是贴地的&#xff0c;使用 Cesium 的primitives功能加载特定…

函数---逆序输出

数字的逆序输出 记住&#xff1a; n n * 10 number % 10; number number / 10; #include <stdio.h> # include <math.h>unsigned int reverse( unsigned int number );int main() {unsigned int n;scanf("%u", &n);printf("%u\n", r…

【JVM】JVM 内存结构

程序计数器 Cpu 要不停的切换执行线程&#xff0c;所以在切换回同一个线程的时候要知道程序执行到哪了&#xff0c;程序计数器&#xff08;PC 计数器&#xff09;&#xff0c;用来存储指向下一条指令的地址&#xff0c;也就是将要执行的代码。 程序的分支、循环、跳转、异常处…

Android12 MultiMedia框架之MediaExtractorService

上节学到setDataSource()时会创建各种Source&#xff0c;source用来读取音视频源文件&#xff0c;读取到之后需要demux出音、视频、字幕数据流&#xff0c;然后再送去解码。那么负责进行demux功能的media extractor模块是在什么时候阶段创建的&#xff1f;这里暂时不考虑APP创建…

6 月份获得了 10000 星的开源项目!

01 开源学习资源的宝库 在这个信息爆炸的时代&#xff0c;想要深入学习一项技术&#xff0c;却常常被海量资源淹没。别担心&#xff0c;Build Your Own X 项目来帮你&#xff01; 这是一个集合了各种技术主题的开源学习资源库&#xff0c;旨在引导开发者通过实践来掌握核心概念…

提升入住率|智慧酒店解决方案,打造有温度的居住体验!

近年来&#xff0c;智慧酒店被越来越多的人关注&#xff0c;由生物识别、物联网技术和互联网技术融合产生的智慧酒店解决方案&#xff0c;不仅可以提升顾客在酒店的入住体验&#xff0c;还可以帮助酒店降低运营成本&#xff0c;这也让越来越的酒店选择了智慧酒店的赛道&#xf…

【windows|012】光猫、路由器、交换机详解

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 ​ &#x1f3c5;阿里云ACE认证高级工程师 ​ &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社…

CV每日论文--2024.6.28

1、On Scaling Up 3D Gaussian Splatting Training 中文标题&#xff1a;扩展 3D 高斯泼溅训练 简介&#xff1a;3D高斯点描(3DGS)由于其卓越的视觉质量和渲染速度,越来越受欢迎用于3D重建。然而,3DGS的训练目前仅在单个GPU上进行,由于内存限制,它的处理高分辨率和大规模3D重建…

基于C语言+控制台的学生信息管理系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、Php、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

Python:Python环境搭建

二、Python环境搭建 1.Python安装指南 &#xff08;1&#xff09;打开文件夹双击python-3.8.5-amd64.exe&#xff0c;进入安装页面&#xff0c;选择自定义安装&#xff0c;并且勾选环境变量。 &#xff08;2&#xff09;自定义安装时&#xff0c;跳出窗口&#xff0c;所有功能…

大力出奇迹:大语言模型的崛起与挑战

随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;特别是在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;大语言模型&#xff08;LLM&#xff09;的出现与应用&#xff0c;彻底改变了我们与机器互动的方式。本文将探讨ChatGPT等大语言模型的定义、…

IPIDEA代理IP助力高效数据采集

IPIDEA代理IP助力高效数据采集 文章目录 IPIDEA代理IP助力高效数据采集&#x1f4d1;前言一、爬虫数据采集痛点二、代理IP解决爬虫痛点2.1 为什么可以2.2 选择代理IP的关键因素 三、IPIDEA海外IP代理的优势3.1 IPIDEA的显著优势3.2 IPIDEA的代理类型及应用 四、IPIDEA爬虫实战4…

复分析——第10章——Θ函数应用(E.M. Stein R. Shakarchi)

第10章 Θ函数的应用 (Applications of Theta Functions) The problem of the representation of an integer n as the sum of a given number k of integral squares is one of the most celebrated in the theory of numbers. Its history may be traced back to Diopha…

JS逆向技巧总结

总的来说&#xff0c;JavaScript 逆向可以分为三大部分&#xff1a;寻找入口、调试分析和模拟执行。下面分别进行介绍。 一&#xff0c;寻找入口 一个网站加载了很多 JavaScript 文件&#xff0c;那么怎么从这么多 JavaScript 里面找到关键的位置&#xff0c;那就是一个关键问…

Outlook发送大文件的问题是什么?怎么解决?

Outlook不仅是一款电子邮件客户端&#xff0c;还包括日历、任务、笔记、联系人等功能&#xff0c;同时与Microsoft Office套件中的其他应用程序&#xff08;如Word、Excel、PowerPoint等&#xff09;集成紧密&#xff0c;方便用户在不同应用程序之间切换&#xff0c;提高工作效…

计算机毕业设计Python+Spark股票基金推荐与预测系统 股票基金可视化 股票基金推荐系统 股票基金可视化系统 股票基金数据分析 股票基金爬虫大数据

目 录 摘 要 Abstract 第1章 前 言 1.1 项目的背景和意义 1.2 研究现状 1.3 项目的目标和范围 1.4 论文结构简介 第2章 技术与原理 2.1 开发原理 2.2 开发工具 2.3 关键技术 第3章 需求建模 3.1 系统可行性分析 3.2 功能需求分析 3.3 非功能性…

Kafka-服务端-副本同步-源码流程

杂 在0.9.0.0之前&#xff0c;Kafka提供了replica lag.max.messages 来控制follower副本最多落后leader副本的消息数量&#xff0c;follower 相对于leader 落后当超过这个数量的时候就判定该follower是失效的&#xff0c;就会踢出ISR&#xff0c;这里的指的是具体的LEO值。 对…

为Stable Diffusion换件新衣服

你是不是已经看腻Stable Diffusion默认的webui了&#xff0c;想要换件新衣服。Lobe Theme这个插件就可以帮助你。 首先&#xff0c;我们启动 SD&#xff0c;如果没有安装&#xff0c;可以参考https://mp.csdn.net/mp_blog/creation/editor/139196688。 然后找到扩展选项卡&…

网络安全--计算机网络安全概述

文章目录 网络信息系统安全的目标网络安全的分支举例P2DR模型信息安全模型访问控制的分类多级安全模型 网络信息系统安全的目标 保密性 保证用户信息的保密性&#xff0c;对于非公开的信息&#xff0c;用户无法访问并且无法进行非授权访问&#xff0c;举例子就是&#xff1a;防…