C# WPF上位机开发(会员管理软件)

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

        好多同学都认为上位机只是纯软件开发,不涉及到硬件设备,比如听听音乐、看看电影、写写小的应用等等。如果是消费电子,确实可能是这种情况。但是除了消费电子、互联网领域之外,上位机还可能涉及到工业生产、医疗和军工领域,每一个细分市场都有很大的规模。这个时候,上位机就可能需要通过USB、can、232、485、网络等很多cabel形式和外部设备进行沟通,那么上位机的功能边际就会一下子拓展很多。此外,就算是同一个领域,不同的行业也都会有不同的know-how,很多的know-how就是以软件的形式固化在软件逻辑里面的,这就是上位机真正的竞争力。

        当然说了这么多,今天我们还是从简单的会员管理软件说起。通俗一点说,它就是简单的学生管理系统。所以的文件需要保存到一个文本里面,通常可以认为是json形式。软件启动后,界面可以完成增删改查的操作。当然,我们可以说增删改查不是那么高端,但它确实软件开发很基础的一个环节。

1、确定文件保存的形式,比如data.json

{"count": 6,"items": [{"ID": 1,"NAME": "aaa"},{"ID": 2,"NAME": "bbb"},{"ID": 3,"NAME": "ccc"},{"ID": 5,"NAME": "ddd"},{"ID": 6,"NAME": "eee"},{"ID": 4,"NAME": "fff"}]
}

        目前如果不用数据库的话,比较方便数据读取和保存的方式就是json格式。如上图所示,这里包含了数据的基本信息,包括了数据的数量,每一组数据的ID和NAME等等。

2、使用Newtonsoft.Json库读写json文件

        前面我们决定用json格式读写文件,接下来需要面对的问题就是如何解析和保存这些数据。好在NuGet上面可以通过第三方库Newtonsoft.Json来直接解析json文件,这就变得非常方便了。

3、设计界面

        界面部分的设计不难。简单一点难说,可以分成两个部分。左边就是数据的增删改查工作,右边就是当前所有数据的显示部分。之所以要添加右边这部分显示内容,主要还是为了直观地去观察,我们当前的操作有没有问题。

        设计好界面之后,再转成xaml代码就不难了,

<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="MemberInfo" Height="300" Width="800"><Grid><RadioButton x:Name="radio_add" Checked="Add_Checked" Content="add" HorizontalAlignment="Left" Margin="51,44,0,0" VerticalAlignment="Top"/><RadioButton x:Name="radio_del" Checked="Del_Checked" Content="del" HorizontalAlignment="Left" Margin="129,44,0,0" VerticalAlignment="Top"/><RadioButton x:Name="radio_update" Checked="Update_Checked" Content="update" HorizontalAlignment="Left" Margin="194,44,0,0" VerticalAlignment="Top"/><RadioButton x:Name="radio_search" Checked="Search_Checked" Content="search" HorizontalAlignment="Left" Margin="284,44,0,0" VerticalAlignment="Top"/><Label Content="ID:" HorizontalAlignment="Left" Margin="75,97,0,0" VerticalAlignment="Top"/><TextBox x:Name="id" HorizontalAlignment="Left" Height="23" Margin="193,97,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120"/><Label Content="Name" HorizontalAlignment="Left" Margin="75,134,0,0" VerticalAlignment="Top"/><TextBox x:Name="name" HorizontalAlignment="Left" Height="23" Margin="193,138,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120" RenderTransformOrigin="0.498,2.609"/><Button Content="OK" Click="OK_Click" HorizontalAlignment="Left" Margin="51,202,0,0" VerticalAlignment="Top" Width="75"/><Button Content="Cancel" Click="Cancel_Click" HorizontalAlignment="Left" Margin="157,202,0,0" VerticalAlignment="Top" Width="75"/><Button Content="Save" Click="Save_Click" HorizontalAlignment="Left" Margin="263,202,0,0" VerticalAlignment="Top" Width="75"/><Label Content="Member Details" HorizontalAlignment="Left" Margin="435,38,0,0" VerticalAlignment="Top"/><TextBox x:Name="all_data" HorizontalAlignment="Left" Height="146" Margin="435,75,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="315"/><Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="235" Margin="395,10,0,0" VerticalAlignment="Top" Width="376"/><Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="235" Margin="15,10,0,0" VerticalAlignment="Top" Width="360"/></Grid>
</Window>

        软件部分的控件都是常见的控件,比如RadioButton、Label、TextBox、Button,同时为了进行左右区别,我们还额外添加了一个Boarder,这样稍微美观一点。

4、代码编写

        代码整体上难度不大,最重要的就是OK按钮的处理,因为它需要判断下当前是哪一种操作模式,是添加,还是其他的操作模式。每一种操作模式的处理逻辑也是不一样的。这部分内容大家可以直接查看OK_Click的函数内容。

        除了OK按钮的处理之外,另外比较重要的代码,就是json文件的加载和保存。加载是在软件启动的时候自动加载的,而保存则需要用户单击Save按钮才会自动保存。

        最后大家可以关注下update_data这个函数,只要是正常的操作,数据内容发生变化,都会调用这个函数更新Textbox里面的内容。

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.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;using Newtonsoft.Json;
using Newtonsoft.Json.Linq;namespace WpfApp
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{private int select_option = 0;private int total = 0;private int[] id_array = new int[1000];private string[] name_array = new string[1000];public MainWindow() // construct function{InitializeComponent();// initialize datafor(int i = 0; i < 1000;i++){id_array[i] = 0;name_array[i] = "";}// load file defined hereload_file();radio_add.IsChecked = true; // set as default value//display data hereall_data.Text = "";all_data.IsEnabled = false;update_data();}private void load_file(){string jsonfile = "data.json";JObject jObject;JToken items;// parse script fileusing (System.IO.StreamReader file = System.IO.File.OpenText(jsonfile)){using (JsonTextReader reader = new JsonTextReader(file)){jObject = (JObject)JToken.ReadFrom(reader);}}// fetch data from json scripttotal = Convert.ToInt32(jObject["count"].ToString());if(total <= 0){return;}items = jObject["items"];if(items == null){return;}// fetch each datafor (int i = 0; i < total; i ++){int id = Convert.ToInt32(items[i]["ID"].ToString());string name = items[i]["NAME"].ToString();id_array[i] = id;name_array[i] = name;}}private void OK_Click(object sender, RoutedEventArgs e){int id_val;string name_val = name.Text;int i = 0;int j = 0;if (id.Text == ""){MessageBox.Show("ID input should not be empty!");return;}id_val = Convert.ToInt32(id.Text);if(id_val >= 1000){MessageBox.Show("ID should be smaller than 1000!");goto Final;}switch(select_option){case 1: //addif(name_val == ""){MessageBox.Show("Name can not be empty!");goto Final;}if (total == 1000){MessageBox.Show("Array is full!");goto Final;}for (i = 0; i < total; i++){if(id_array[i] == id_val){MessageBox.Show("Find same id!");goto Final;}}id_array[total] = id_val;name_array[total] = name_val;total += 1;MessageBox.Show("Add successfully!");break;case 2://delif (total == 0){MessageBox.Show("Array is empty!");goto Final;}for (i = 0; i < total; i++){if (id_array[i] == id_val){break;}}if(i == total){MessageBox.Show("Failed to find relevant id!");goto Final;}for(j = i+1; j < total; j++){id_array[j - 1] = id_array[j];name_array[j - 1] = name_array[j];}total -= 1;MessageBox.Show("Del successfully!");break;case 3://updateif (name_val == ""){MessageBox.Show("Name can not be empty!");goto Final;}if (total == 0){MessageBox.Show("Array is empty!");goto Final;}for (i = 0; i < total; i++){if (id_array[i] == id_val){break;}}if (i == total){MessageBox.Show("Failed to find relevant id!");goto Final;}name_array[i] = name_val;MessageBox.Show("Update successfully!");break;case 4://searchif (total == 0){MessageBox.Show("Array is empty!");goto Final;}for (i = 0; i < total; i++){if (id_array[i] == id_val){break;}}if (i == total){MessageBox.Show("Failed to find relevant id!");goto Final;}MessageBox.Show("Name is " + name_array[i]);break;default:break;}// display dataupdate_data();Final:id.Text = "";name.Text = "";}private void update_data(){string data_text = "";for(int i = 0; i < total;i++){data_text += Convert.ToString(id_array[i]);data_text += " ";data_text += name_array[i];data_text += "\n";}all_data.Text = "";all_data.Text = data_text;}private void Cancel_Click(object sender, RoutedEventArgs e){this.Close();}private void Save_Click(object sender, RoutedEventArgs e) // important callback function{JArray items = new JArray();JObject header = new JObject();// save to arrayfor(int i = 0; i < total; i++){JObject jobj = new JObject();jobj["ID"] = id_array[i];jobj["NAME"] = name_array[i];items.Add(jobj);}// save to headerheader["count"] = total;header["items"] = items;// save datausing (System.IO.StreamWriter file = new System.IO.StreamWriter("data.json")){file.Write(header.ToString());}MessageBox.Show("Save successfully!");}private void Add_Checked(object sender, RoutedEventArgs e){select_option = 1; //addname.IsEnabled = true;}private void Del_Checked(object sender, RoutedEventArgs e){select_option = 2; //delname.Text = "";name.IsEnabled = false;}private void Update_Checked(object sender, RoutedEventArgs e){select_option = 3; //updatename.IsEnabled = true;}private void Search_Checked(object sender, RoutedEventArgs e){select_option = 4; //searchname.Text = "";name.IsEnabled = false;}}
}

        至于说代码中的入参处理、异常处理、使用习惯处理,这些部分只能靠大家自己去慢慢体会和了解了。有了这份代码做基础,以后的crud代码,也就是增删改查操作都逃不了这个范畴。而且我们的数据是真正保存在json文件中的,不存在丢失的风险,这也让开发的软件进一步拓展了实用性和可靠性。

5、运行测试

        运行测试就比较简单了,直接编译执行就好了,不出意外就可以看到这样的运行画面了,和之前设计稍微有点区别,

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

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

相关文章

HibernateJPA快速搭建

1. 先创建一个普通Maven工程&#xff0c;导入依赖 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><depe…

Java 匿名内部类使用的外部变量,为什么一定要加 final?

问题描述 Effectively final Java 1.8 新特性&#xff0c;对于一个局部变量或方法参数&#xff0c;如果他的值在初始化后就从未更改&#xff0c;那么该变量就是 effectively final&#xff08;事实 final&#xff09;。 这种情况下&#xff0c;可以不用加 final 关键字修饰。 …

报错:Parsed mapper file: ‘file mapper.xml 导致无法启动

报错 &#xff1a; Logging initialized using class org.apache.ibatis.logging.stdout.StdOutImpl adapter. Registered plugin: com.github.yulichang.interceptor.MPJInterceptor3b2c8bda Parsed mapper file: file [/Mapper.xml] application无法启动 我这边产生原因是项…

! [remote rejected] master -> master (pre-receive hook declined)

! [remote rejected] master -> master (pre-receive hook declined) 如图&#xff1a; 出错解决方法 首先输入命令 git branch xindefenzhi然后&#xff0c;进入这个新创建的分支 git checkout branch然后重新git push就可以了

爬虫学习-基础库的使用(urllib库)

目录 一、urllib库介绍 二、request模块使用 &#xff08;1&#xff09;urlopen ①data参数 ②timeout参数 &#xff08;2&#xff09;request &#xff08;3&#xff09;高级用法 ①验证 ②代理 ③Cookie 三、处理异常 ①URLError ②HTTPError 四、解析链接 ①urlparse ②…

Kernel(一):基础

本文主要讨论210的kernel基础相关知识。 内核驱动 驱动是内核中的硬件设备管理模块,工作在内核态,程序故障可能导致内核崩溃,程序漏洞会使内核不安全 根文件系统提供根目录,进程存放在根文件系统中,内核启动最后会装载根文件系统 应用程序不属于内核,…

1828_ChibiOS中的对象FIFO

全部学习汇总&#xff1a; GreyZhang/g_ChibiOS: I found a new RTOS called ChibiOS and it seems interesting! (github.com) 1. 最初的这个理解&#xff0c;当看到后面之后就知道有点偏差了。其实&#xff0c;这个传输就是一个单纯的FIFO而不是两个FIFO之间的什么操作。 2.…

去掉参数中第一个“,”

记录一下&#xff0c;前端传参中&#xff0c;传给我参数是“categoryIds: ,1731557494586241026,1731569816263311362,1731569855534579713,1731858335179223042,1731858366821052418” 但是后端&#xff0c;因为我的mybati是in查询&#xff0c;所以因为第一个是“,”。所以会导…

sap增强

四代增强 2种显示增强1种隐式增强 隐式增强 光标放在增强点或其中的代码点击修改即可修改代码 显示增强 1.ENHANCEMENT-POINT 在代码修改界面选择空行 光标所在位置 可以创建多个增强实施且激活后都会执行. 2.ENHANCEMENT-SECTION 1,选中程序中空行 2.编辑->创建选项 …

回顾2023 亚马逊云科技 re_Invent,创新AI,一路同行

作为全球云计算龙头企业的亚马逊云科技于2023年11月27日至12月1日在美国拉斯维加斯举办了2023 亚马逊云科技 re:Invent&#xff0c;从2012年开始举办的亚马逊云科技 re:Invent 全球大会,到现如今2023 亚马逊云科技 re:Invent&#xff0c;回顾历届re:Invent大会&#xff0c;亚马…

C++『异常』

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; C修行之路 &#x1f383;操作环境&#xff1a; Visual Studio 2022 版本 17.6.5 文章目录 &#x1f307;前言&#x1f3d9;️正文1.异常基本概念1.1.C语言异常处理方式1.2.C异常处理方式 2.异常的使用2.1.异常…

在线网页生成工具GrapesJS

项目地址 https://github.com/GrapesJS/grapesjshttps://github.com/GrapesJS/grapesjs 项目简述 这是一个基于node.js的在线网页生成项目&#xff0c;对简化开发有很大的帮助。 主要使用的语言如下&#xff1a; 编辑页面如下&#xff1a; 使用也很简洁 具体可以看下项目。…

12. MySQL 锁机制

目录 概述 MylSAM引擎 InnoDB引擎 概述 锁是计算机协调多个进程或线程并发访问某一资源的机制&#xff08;避免争抢&#xff09;。在数据库中&#xff0c;除传统的计算资源(如CPU、RAM、I/O等&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的资如何保证数据…

2023年第十届GIAC全球互联网架构大会-核心PPT资料下载

一、峰会简介 谈到一个应用&#xff0c;我们首先考虑的是运行这个应用所需要的系统资源。其次&#xff0c;是关于应用自身的架构模式。最后&#xff0c;还需要从软件工程的不同角度来考虑应用的设计、开发、部署、运维等。架构设计对应用有着深远的影响&#xff0c;它的好坏决…

Leetcode659. 分割数组为连续子序列

Every day a Leetcode 题目来源&#xff1a;659. 分割数组为连续子序列 解法1&#xff1a;哈希 贪心 定义两个哈希表&#xff1a; numsCount&#xff1a;统计数组 nums 中各元素出现次数。tailCount&#xff1a;存储以数字 i 结尾的且符合题意的连续子序列个数。 算法&a…

极兔单号查询,极兔快递物流查询,一键筛选出退回件

批量查询极兔快递单号的物流信息&#xff0c;一键筛选出其中的退回件。 所需工具&#xff1a; 一个【快递批量查询高手】软件 极兔快递单号若干 操作步骤&#xff1a; 步骤1&#xff1a;运行【快递批量查询高手】软件&#xff0c;并登录 步骤2&#xff1a;点击主界面左上角的…

【Bootloader学习理解----跳转优化异常】

笔者接着来介绍一下Bootloader的跳转代码以及优化 1、跳转代码理解 跳转代码可能要涉及到芯片架构的知识,要跳转到对应的位置&#xff0c;还要设置相关的SP 堆栈指针&#xff0c;具体可以参考笔者这篇文章BootLoader的理解与实现。 STM32的跳转代码如下所示&#xff1a; u32 …

基于以太坊的智能合约开发Solidity(基础篇)

参考教程&#xff1a;基于以太坊的智能合约开发教程【Solidity】_哔哩哔哩_bilibili 1、第一个程序——Helloworld&#xff1a; //声明版本号&#xff08;程序中的版本号要和编译器版本号一致&#xff09; pragma solidity ^0.5.17; //合约 contract HelloWorld {//合约属性变…

Python轴承故障诊断 (四)基于EMD-CNN的故障分类

目录 前言 1 经验模态分解EMD的Python示例 2 轴承故障数据的预处理 2.1 导入数据 2.2 制作数据集和对应标签 2.3 故障数据的EMD分解可视化 2.4 故障数据的EMD分解预处理 3 基于EMD-CNN的轴承故障诊断分类 3.1 训练数据、测试数据分组&#xff0c;数据分batch 3.2 定义…

stu05-前端的几种常用开发工具

前端的开发工具有很多&#xff0c;可以说有几十种&#xff0c;包括记事本都可以作为前端的开发工具。下面推荐的是常用的几种前端开发工具。 1.DCloud HBuilder&#xff08;轻量级&#xff09; HBuilder是DCloud&#xff08;数字天堂&#xff09;推出的一款支持HTML5的web开发…