C# WPF上位机开发(增强版绘图软件)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        前面我们写过一个绘图软件,不过那个比较简单,主要就是用鼠标模拟pen进行绘图。实际应用中,另外一种使用比较多的场景,就是绘制直线、长方形和圆形。不管是流程图,还是传感器仿真,或者是图形数据动态显示等等,绘图部分本身还是有着重要的实际用途。因此,这里有必要告诉大家,实际的canvas绘图是什么样的。

        这里的增强版,主要也是指的直线绘图、长方形绘图和圆形绘图。当然如果要做得好的话,一般还需要同步考虑一下keyboard事件,这部分也很重要。

1、软件设计

        关于软件设计,目前是这么考虑的。可以创建一个菜单,里面有三个子菜单,这三个子菜单分别是直线、长方形和圆形。我们选择了一种图形,那么其他的图形就自动被放弃。后续在canvas上面绘图的时候,就用对应子菜单的形式进行绘图即可。

2、界面设计

        相对代码,界面设计还是比较简单的。整个界面主要就两个部分,一部分是菜单,一部分是canvas。做好了这个,基本的界面就准备好了。

<Window x:Class="WpfApp.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp"mc:Ignorable="d"Title="Canvas" Height="450" Width="600"><Grid><Menu Name="shapesMenu"><MenuItem Header="Shapes"><MenuItem Name="menuItemLine" Header="Line" IsCheckable="True" IsChecked="false" Checked="MenuItemLine_Checked"/><MenuItem Name="menuItemRectangle" Header="Rectangle" IsCheckable="True" IsChecked="False" Checked="MenuItemRectangle_Checked"/><MenuItem Name="menuItemCircle" Header="Circle" IsCheckable="True" IsChecked="False" Checked="MenuItemCircle_Checked"/></MenuItem></Menu><Canvas Name="drawingCanvas" Background="WhiteSmoke" MouseDown="Canvas_MouseDown" MouseMove="Canvas_MouseMove" MouseUp="Canvas_MouseUp" Margin="0,20,0,10"/></Grid>
</Window>

3、代码设计

        由于是绘图,所以整个绘图的操作其实分成了三个阶段,分别是鼠标左键按下、鼠标移动、鼠标松开三个步骤。如果是鼠标按键刚刚按下,一般只需要记录一下当前的坐标即可。接着在鼠标移动的时候,开始绘制图形。等到最终鼠标左键弹起的时候,绘图结束,所有的shape记录到List当中。

        当然除了绘图之外,另外一部分比较重要的就是菜单的响应,这里建议不同的菜单设置不同的响应函数。虽然麻烦了一点,但是可以保证不出错。

4、详细的代码内容

        最后为了方便学习和交流,这里给出完整的c#代码,中间关于图形绘制的内容多了一点,菜单部分的内容其实还是比较简单的。

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;namespace WpfApp
{public partial class MainWindow : Window{private Point startPoint;private bool isDrawing = false;private Shape currentShape;private List<Shape> shapes = new List<Shape>();// init MainWindowpublic MainWindow(){InitializeComponent();}// mouse down functionprivate void Canvas_MouseDown(object sender, MouseButtonEventArgs e){startPoint = e.GetPosition(drawingCanvas);isDrawing = true;}// mouse move functionprivate void Canvas_MouseMove(object sender, MouseEventArgs e){if (isDrawing){Point endPoint = e.GetPosition(drawingCanvas);if (currentShape == null){// Determine the shape type based on the selected menu itemif (menuItemLine.IsChecked){currentShape = new Line { Stroke = Brushes.Blue, StrokeThickness = 2 };}else if (menuItemRectangle.IsChecked){currentShape = new Rectangle { Stroke = Brushes.Red, StrokeThickness = 2, Fill = Brushes.Transparent };}else if(menuItemCircle.IsChecked){currentShape = new Ellipse { Stroke = Brushes.Green, StrokeThickness = 2, Fill = Brushes.Transparent };}else{currentShape = null;return;}drawingCanvas.Children.Add(currentShape);}// Update the coordinates of the shapeif (currentShape is Line line){line.X1 = startPoint.X;line.Y1 = startPoint.Y;line.X2 = endPoint.X;line.Y2 = endPoint.Y;}else if (currentShape is Rectangle rectangle){double width = endPoint.X - startPoint.X;double height = endPoint.Y - startPoint.Y;rectangle.Width = width > 0 ? width : -width;rectangle.Height = height > 0 ? height : -height;// record first xif(startPoint.X < endPoint.X)Canvas.SetLeft(rectangle, startPoint.X);elseCanvas.SetLeft(rectangle, endPoint.X);// record first yif(startPoint.Y < endPoint.Y)Canvas.SetTop(rectangle, startPoint.Y);elseCanvas.SetTop(rectangle, endPoint.Y);}else if(currentShape is Ellipse ecllipse){double width = endPoint.X - startPoint.X;double height = endPoint.Y - startPoint.Y;ecllipse.Width = width > 0 ? width : -width;ecllipse.Height = height > 0 ? height : -height;// judge ecllipse width and heightif(ecllipse.Width > ecllipse.Height){ecllipse.Height = ecllipse.Width;}else{ecllipse.Width = ecllipse.Height;}// record first xif (startPoint.X < endPoint.X)Canvas.SetLeft(ecllipse, startPoint.X);elseCanvas.SetLeft(ecllipse, endPoint.X);// record first yif (startPoint.Y < endPoint.Y)Canvas.SetTop(ecllipse, startPoint.Y);elseCanvas.SetTop(ecllipse, endPoint.Y);}else{return;}}}// mouse up functionprivate void Canvas_MouseUp(object sender, MouseButtonEventArgs e){isDrawing = false;if (null != currentShape){shapes.Add(currentShape);currentShape = null;}}// sub menu functionprivate void MenuItemLine_Checked(object sender, RoutedEventArgs e){menuItemLine.IsChecked = true;menuItemRectangle.IsChecked = false;menuItemCircle.IsChecked = false;}// sub menu functionprivate void MenuItemRectangle_Checked(object sender, RoutedEventArgs e){menuItemLine.IsChecked = false;menuItemRectangle.IsChecked = true;menuItemCircle.IsChecked = false;}// sub menu functionprivate void MenuItemCircle_Checked(object sender, RoutedEventArgs e){menuItemLine.IsChecked = false;menuItemRectangle.IsChecked = false;menuItemCircle.IsChecked = true;}}
}

5、结束彩蛋部分

        另外建议大家可以多使用类似chatgpt的工具来学习c# wpf,这样你给它提示关键字,通过不断的交流,最终一定可以实现你想要的效果。这比单纯的搜索引擎学习效率要高得多。

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

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

相关文章

【Git 小妙招】学习 Git 能干什么(了解+安装)

文章目录 前言1. Git 专栏目标2. Git 初识2.1 思考场景2.2 版本控制器2.3 注意事项 3. Git 安装3.1 在 Linux 上安装3.1.1 CentOS3.1.2 Ubuntu 3.2 在 macOS 上安装3.3 在 Windows 上安装 总结 前言 打开本文将正式开启 Git 的学习之旅&#xff0c;将手把手带领大家从零开始学…

Leetcode—509.斐波那契数【简单】

2023每日刷题&#xff08;五十七&#xff09; Leetcode—509.斐波那契数 实现代码 int fib(int n){if(n 0) {return 0;}if(n 1) {return 1;}return fib(n-1) fib(n-2); }运行结果 之后我会持续更新&#xff0c;如果喜欢我的文章&#xff0c;请记得一键三连哦&#xff0c;点…

go的结构体作为返回值

结构体有两种方式作为返回值 结构体结构体指针 代码 package mainimport ("fmt" )type SS struct {Name stringAge int }func getInfo() (*SS) {var ac SS{}ac.Age 1return &ac }func getInfo1() (aa *SS) {aa.Age 1return }func getInfo2() (SS) {var ac…

网络安全公司梳理,看F5如何实现安全基因扩增

应用无处不在的当下&#xff0c;从传统应用到现代应用再到边缘、多云、多中心的安全防护&#xff0c;安全已成为企业数字化转型中的首要挑战。根据IDC2023年《全球网络安全支出指南》&#xff0c;2022年度中国网络安全支出规模137.6亿美元&#xff0c;增速位列全球第一。有专家…

SMOTE 过采样,解决正负样本不均衡问题

一、SMOTE过采样 1.1 问题 在实际业务中&#xff0c;样本不均衡&#xff08;即正负样本比例严重失衡&#xff09;是一种常见的问题。这种情况下&#xff0c;传统的机器学习算法可能会倾向于偏向占主导地位的类别&#xff0c;从而导致模型性能下降。 1.2 SMOTE方法 为了解决…

Scss和less预处理器的使用对比

变量(Variables) scss变量标识符是&#xff1a;$ $primary-color: red; div {background: $primary-color; }less变量标识符&#xff1a; primary-color: red; div {background: primary-color; }变量名称规则&#xff1a;scss下划线和横线相互兼容, less中定义的名称和使用…

磁力计LIS2MDL开发(1)----轮询获取磁力计数据

磁力计LIS2MDL开发.1--轮询获取磁力计数据 概述视频教学样品申请源码下载通信模式速率生成STM32CUBEMX串口配置IIC配置CS设置串口重定向参考程序初始换管脚获取ID复位操作BDU设置设置速率启用偏移消除开启温度补偿设置为连续模式轮询读取数据主程序演示 概述 本文将介绍如何使…

[网络安全]批处理(脚本)编写

Windows DOS命令Linux 一.作用: 自上而下成批次处理每一条命令,直到执行到最后一条 二.如何创建批处理: 扩展名:.bat创建办法:新建一个记事本,把扩展名改为 .bat 三.编辑方法: 右击 -编辑 1).一行一个命令 四.批处理命令: pause 暂停 (及时后面有命令,也不执行)echo …

Knowledge Graph知识图谱—9. Data Quality and Linking

9. Data Quality and Linking 9.1 How well are the linked open data in practice? Linked Open Vocabularies(LOV) project – analyze usage of vocabularies 9.2 Quality Linked Data Conformance vs. Quality Conformance: – i.e., following standards and best prac…

【git push ERROR: commit id: missing Change-Id in message footer】

使用 gerrit 后&#xff0c;提交代码会出现如下截图问题&#xff1a; 临时解决&#xff1a; step1: 把上面红色的那条gitidir复制下来执行下&#xff1a; step2:执行下面的命令会添加change_id git commit --amendstep3: 然后推送代码到服务器上 git push origin HEAD:refs/fo…

事件驱动架构 vs. RESTful架构:通信模式对比与选择

1. 通信风格 事件驱动架构&#xff08;EDA&#xff09; 是一种异步通信风格&#xff0c;组件之间通过产生和消费事件进行通信。 事件是表示系统中重大变化或事件的消息&#xff0c;并分发给感兴趣的组件。这种通信模型允许系统的不同部分之间进行解耦和动态交互。 组件充当事件…

新手上路:盘点「性能测试」必须掌握的技术点

前段时间&#xff0c;有一些小伙伴提出希望我们推送点性能测试的技术干货。所以&#xff0c;小编今天通过上网查资料&#xff0c;结合项目实操过程中的一些问题&#xff0c;总结了一些关于性能测试的内容&#xff0c;希望是大家想要了解的内容哈。 1、性能测试的目的 首先&am…

Java中JDK类库常用的6种设计模式

Java中JDK类库常用的6种设计模式&#xff1a;1、抽象工厂。2、建造者模式。3、工厂模式。4、原型模式。5、单例模式。6、适配器模式。 1、抽象工厂 javax.xml.parsers.DocumentBuilderFactory抽象类。 public static DocumentBuilderFactory newInstance()方法。 类功能&…

.Net中的集合

所有的集合都是继承自IEnumerable。集合总体可以分为以下几类&#xff1a;关联/非关联型集合&#xff0c;顺序/随机访问集合&#xff0c;顺序/无序集合&#xff0c;泛型/非泛型集合&#xff0c;线程集合。 各集合类底层接口关系图 泛型与非泛型集合类的分析 泛型集合是类型安…

离散数学 速成

文章目录 一、命题逻辑的基本概念1. 命题2. 命题联结词 二、命题逻辑等值演算1. 等值式&#x1f330;子 2. 析取范式和合取范式&#x1f330;子 3. 主析取范式和主合取范式&#x1f330;子 4. 联结词的完备集&#x1f330;子 三、命题逻辑的推理理论&#x1f330;子 一、命题逻…

复制时源数据中null值不复制到

问题场景 例如有个对象要新增&#xff0c;后面的新增&#xff0c;我们希望判断一下是否有这个数据&#xff0c;如果有&#xff0c;则对上次提交的完善。如果没有&#xff0c;就新增。那么用其他方式实现很麻烦&#xff0c;本身的BeanUtils.copyProperties也是不大支持。 我们…

Java - Math类的常用方法及练习

目录 1.1 概述 1.2 常用方法 ❓面试题&#xff1a;为啥Math.round(-1.5)-1? 1.1 概述 java.lang.Math 类包含用于执行基本数学运算的方法&#xff0c;如初等指数、对数、平方根和三角函数。类似这样的工具类&#xff0c;其所有方法均为静态方法&#xff0c;并且不会创建对象…

优雅玩转实验室服务器(三)vscode is all you need

在前两章解决了传输问题和连接问题后&#xff0c;我们紧接着遇到一个新的需求&#xff1a;我们需要coding呀&#xff0c;你当然可以说&#xff0c;我们可以用vim和对应的插件来搭建一个IDE呀&#xff0c;fine&#xff0c;我甚至可以给你推荐如下的教程&#xff1a; Vim 到底可…

oracle详细安装教程(附带百度网盘资源)

一,下载安装包途径 1.官网 Unauthorized Request 2.百度网盘分析 https://pan.baidu.com/s/1n221gdTK0Fcho839oRab9g 提取码1q2w 二&#xff0c;安装教程 1.下载完安装包后点击 setup.exe 如果出现一下的问题&#xff0c;使用windows10等系统安装oracle 11g等版本的数据库…

实验7:索引和视图定义

【实验目的】 1、了解索引和视图的含义 2、熟悉索引和视图的创建规则 3、掌握索引和视图的创建和管理 【实验设备及器材】 1、硬件&#xff1a;PC机&#xff1b; 2、软件&#xff1a;(1)Windows7; (2)Microsoft SQL Server 2012。 【主要内容】 索引的创建、删除、重建…