C#基础知识-使用XML完成一个小程序(十一)
上一篇中讲到XML基本的结构,还有增删改查的方法,这一篇中我们就来利用XML来完成一个简单的订单系统,主要是实现一个简单学生名单的增删改查,如果想要应用到实际的环境中建议考虑数据量的问题,如果数据量大使用XML的话会比较耗时,使用SQL的性能会好一些
这里使用WinForm窗体程序,大致界面如下:

- 创建了两个窗体,一个主窗体用来显示名单数据,当添加或者编辑操作时则使用另外一个窗体。
- 主窗体中放置四个按钮,以及一个DataGridView控件,另外一个添加、编辑窗体,则按照相应的字段放置好控件。
- 给各控件命好名。
XML文档的格式如下:
<?xml version="1.0" encoding="utf-8"?>
<学生名单>
<学生 Name="李四一" class="0102">
<性别>男</性别>
<生日>1999年1月2日</生日>
<学号>20170</学号>
</学生>
<学生 Name="张三三" class="高一">
<性别>男</性别>
<学号>0102</学号>
<生日>2017年6月18日</生日>
</学生>
</学生名单>
学生名单为根元素,班级为根元素中的子元素,班级中又嵌套<学生>标记,了解了数据是以怎么的结构储存那么下面就继续。
数据在DataGridView中的显示
将XML中的数据,顺序显示在DataGridView控件中
//创建一个datatable存储XML中的数据
DataTable dt = new DataTable();
//指定每一列的列名,和数据类型
dt.Columns.Add("Id", (typeof(System.String)));
dt.Columns.Add("班级", (typeof(System.String)));
dt.Columns.Add("姓名", (typeof(System.String)));
dt.Columns.Add("学号", (typeof(System.String)));
dt.Columns.Add("生日", (typeof(System.String)));
dt.Columns.Add("性别", (typeof(System.String)));
//创建一个DataRow对象
DataRow dr = dt.NewRow();
XmlDocument doc = new XmlDocument();
//为相对路径表示前二级的目录
doc.Load(@"..//..//Students.xml");
XmlElement root = doc.DocumentElement;
XmlNodeList studentNodes = root.GetElementsByTagName("学生");
//使用foreach遍历集合元素
foreach(var item in studentNodes)
{
dr["Id"] = ((XmlElement)item).GetAttribute("Id");
dr["班级"] = ((XmlElement)item).GetAttribute("Class");
dr["姓名"] = ((XmlElement)item).GetAttribute("Name");
dr["学号"] = ((XmlElement)item).GetElementsByTagName("学号")[].InnerText;
dr["生日"] = ((XmlElement)item).GetElementsByTagName("生日")[].InnerText;
dr["性别"] = ((XmlElement)item).GetElementsByTagName("性别")[].InnerText;
dt.Rows.Add(dr);
}
//将DataTable绑定到DataGridView控件
dgvStudents.DataSource = dt;
增加记录
因为添加学生和编辑学生都需要在同一个窗体,那么在打开添加或编辑窗体时使用构造函数来传值,并判断是编辑还是添加。
添加编辑窗体代码:
public partial class FrmStudentAddandEdit : Form
{
//全局变量接受传值
bool IsAdd;
string Name;
//使用构造函数进行传值 true为增加,false为编辑
public FrmStudentAddandEdit(bool isAdd, string name)
{
this.IsAdd = isAdd;
this.Name = name;
InitializeComponent();
}
}
主窗体添加按钮单击事件代码:
private void btnAdd_Click(object sender, EventArgs e)
{
//在创建窗体时传值
FrmStudentAddandEdit form = new FrmStudentAddandEdit(true);
form.ShowDialog();
}
新增记录代码:
private void btnOK_Click(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.Load(@"..//..//Students.xml");
XmlElement root = doc.DocumentElement;
//添加<学生>子节点
XmlElement Shutdent = doc.CreateElement("学生");
//设置Name属性和Class属性
Shutdent.SetAttribute("Name", txtName.Text.Trim());
Shutdent.SetAttribute("Class", txtClass.Text.Trim());
//创建子节点
XmlElement eSex = doc.CreateElement("性别");
XmlText tSex = doc.CreateTextNode(cmbSex.Text.Trim());
//子节点添加内容
eSex.AppendChild(tSex);
//将子节点添加进学生标记
Shutdent.AppendChild(eSex);
XmlElement eNum = doc.CreateElement("学号");
XmlText tNum = doc.CreateTextNode(txtNumber.Text.Trim());
eNum.AppendChild(tNum);
Shutdent.AppendChild(eNum);
XmlElement eBirthday = doc.CreateElement("生日");
XmlText tBirthday = doc.CreateTextNode(dtpBirthday.Text.Trim('-'));
eBirthday.AppendChild(tBirthday);
Shutdent.AppendChild(eBirthday);
//将<学生>标记添加进根节点
root.AppendChild(Shutdent);
doc.Save(@"..//..//Students.xml");
MessageBox.Show("添加成功!");
this.Close();
}
编辑记录
由于编辑需要查找到这条记录然后复制到控件中显示,那么在我们启动”添加或编辑窗体”时需要判断当前是添加状态还是编辑状态,并将表格选择行的姓名字段传给构造函数,通过这个姓名字段查找相应的值,然后筛选出来再给控件赋值。
主窗口编辑按钮单击事件:
private void btnEdit_Click(object sender, EventArgs e)
{
//获取当前选择表格的行索引
int dgvIndex = dgvStudents.CurrentRow.Index;
//根据行索引获取单元格的值
string name = dgvStudents.Rows[dgvIndex].Cells["姓名"].Value.ToString();
FrmStudentAddandEdit form = new FrmStudentAddandEdit(false,name);
form.ShowDialog();
}
窗体启动事件进行判断是添加还是编辑:
private void FrmStudentAddandEdit_Load(object sender, EventArgs e)
{
if (IsAdd)
{
this.Text = "添加学生";
}
else
{
this.Text = "编辑学生名单";
XmlDocument doc = new XmlDocument();
doc.Load(@"..//..//Students.xml");
XmlElement root = doc.DocumentElement;
//筛选出符合条件的标记
XmlElement selectEle = (XmlElement)root.SelectSingleNode("/学生名单/学生[@Name='" + Name + "']");
//筛选出符合条件并给控件赋值
txtName.Text = selectEle.GetAttribute("Name");
txtClass.Text = selectEle.GetAttribute("Class");
txtNumber.Text = selectEle.GetElementsByTagName("学号")[].InnerText;
dtpBirthday.Text = selectEle.GetElementsByTagName("生日")[].InnerText;
cmbSex.Text = selectEle.GetElementsByTagName("性别")[].InnerText;
}
}
同样在编辑好内容后,单击确定按钮后判断当前是添加状态还是编辑状态:
private void btnOK_Click(object sender, EventArgs e)
{
if (IsAdd)
{
//添加记录代码….
}
else
{
this.Text = "编辑学生名单";
XmlDocument doc = new XmlDocument();
doc.Load(@"..//..//Students.xml");
XmlElement root = doc.DocumentElement;
//筛选出符合条件的标记
XmlElement selectEle = (XmlElement)root.SelectSingleNode("/学生名单/学生[@Name='" + Name + "']");
selectEle.SetAttribute("Name",txtName.Text.Trim());
selectEle.SetAttribute("Class",txtClass.Text.Trim());
//筛选出的对象赋给XMLElement对象
XmlElement eSex = (XmlElement)selectEle.GetElementsByTagName("性别")[];
eSex.InnerText = cmbSex.Text;
XmlElement eNumber = (XmlElement)selectEle.GetElementsByTagName("学号")[];
eNumber.InnerText = txtNumber.Text;
XmlElement eBirth = (XmlElement)selectEle.GetElementsByTagName("生日")[];
eBirth.InnerText = dtpBirthday.Text;
doc.Save(@"..//..//Students.xml");
MessageBox.Show("修改成功!");
//这一步很重要一定要关闭窗口不然再次修改会出现不可预料的BUG
this.Close();
}
}
删除记录
也是一样的逻辑获取当前选择表格的姓名字段,然后按照相关姓名进行删除,如果姓名不是唯一字段,那么可以使用ID,每次添加一条记录的时候最大ID+1。
//获取当前选择表格的行索引及姓名
int dgvIndex = dgvStudents.CurrentRow.Index;
string name = dgvStudents.Rows[dgvIndex].Cells["姓名"].Value.ToString();
//筛选出符合条件的标记
XmlElement selectEle = (XmlElement)root.SelectSingleNode("/学生名单/学生[@Name='" + Name + "']");
//删除指定子元素
root.RemoveChild(selectEle);
doc.Save(“…”);
//具体代码省略。。。。。不会的同学可以回到上篇文章。
上面介绍的操作方法是最常使用几种的,可以使用XML来完成一个数据量比较小的软件,或者可以用来做软件的配置文件。
C#基础知识-使用XML完成一个小程序(十一)的更多相关文章
- java操作xml的一个小例子
最近两天公司事比较多,这两天自己主要跟xml打交道,今天更一下用java操作xml的一个小例子. 原来自己操作xml一直用这个包:xstream-1.4.2.jar.然后用注解的方式,很方便,自己只要 ...
- c++学习笔记---02---从一个小程序说起
从一个小程序说起 这一讲的主要目的是帮助大家在C语言的背景知识上与C++建立联系. 问题探索 问题:对一个整型数组求和. 要求:定义一个存储着 n 个元素的数组,要求用C语言完成这个任务. 赶紧的:大 ...
- Python 练习冊,每天一个小程序
Python 练习冊,每天一个小程序 说明: Github 原文地址: 点击打开链接 Python 练习冊.每天一个小程序.注:将 Python 换成其它语言,大多数题目也试用 不会出现诸如「 ...
- 【Java】一个小程序,计算它包含的代码所需的耗时
写一个小程序,用来计算它包含的代码所需的耗时.虽然简单,测试代码是否耗时还是有点用的,不用重新写嘛~ import java.util.Date; import java.util.concurren ...
- c++学习笔记---04---从另一个小程序接着说
从另一个小程序接着说 文件I/O 前边我们已经给大家简单介绍和演示过C和C++在终端I/O处理上的异同点. 现在我们接着来研究文件I/O. 编程任务:编写一个文件复制程序,功能实现将一个文件复制到另一 ...
- c++学习笔记---03---从一个小程序说起2
从一个小程序说起2 要求:编写一个程序,要求用户输入一串整数和任意数目的空格,这些整数必须位于同一行中,但允许出现在该行中的任何位置.当用户按下键盘上的"Enter"键时,数据输入 ...
- 微信小程序开发——打开另一个小程序
微信小程序打开另一个小程序,有两种方法:1.超链接:2.点击按钮. 全局配置: 跳转到其他小程序,需要在当前小程序全局配置中配置需要跳转的小程序列表,代码如下: App.json { ... &quo ...
- 微信小程序如何跳转到另一个小程序
微信小程序如何跳转到另一个小程序,要注意:在app.json文件里也要配置 navigateToMiniProgramAppIdList,如下图: "navigateToMiniProgra ...
- 【小程序】微信小程序打开其他小程序(打开同一主体公众号下关联的另一个小程序)
微信小程序打开其他小程序(打开同一公众号下关联的另一个小程序) 注:只有同一(主体)公众号下的关联的小程序之间才可相互跳转 wx.navigateToMiniProgram(OBJECT) wx.n ...
随机推荐
- 爆款AR游戏如何打造?网易杨鹏以《悠梦》为例详解前沿技术
本文来自网易云社区. 7月31日,2018云创大会游戏论坛在杭州国际博览中心103B圆满举行.本场游戏论坛聚焦探讨了可能对游戏行业发展有重大推动的新技术.新实践,如AR.区块链.安全.大数据等. 网易 ...
- Android 开发怎样做代码加密或混淆?
欢迎访问网易云社区,了解更多网易技术产品运营经验. 在大公司怎么做android代码混淆的?发现他们的软件用apktool反编译居然没看到classes.dex文件和当前安卓APP加固到底该如何做到防 ...
- IO模型《五》异步IO
Linux下的asynchronous IO其实用得不多,从内核2.6版本才开始引入.先看一下它的流程: 用户进程发起read操作之后,立刻就可以开始去做其它的事.而另一方面,从kernel的角度,当 ...
- Mysql数据类型《二》字符类型
字符类型 #官网:https://dev.mysql.com/doc/refman/5.7/en/char.html #注意:char和varchar括号内的参数指的都是字符的长度 #char类型:定 ...
- Codeforces 464E. The Classic Problem
题目大意 给定一张$n$个点, $m$条边的无向图,求$S$ 到$T$的最短路,其中边权都是$2^k$的形式$n,m,k<=10^5$,结果对$10^9+7$取模 题解 大佬好厉害 跑一边dij ...
- Ubuntu更新提示哈希和不匹配“Hash Sum mismatch”
Ubuntu更新提示哈希和不匹配"Hash Sum mismatch" 今天在常规更新软件的时候,我的ubuntu报了一个错误. 应该是ubuntu程序更新转交给另外一个更新造成 ...
- P1642 规划 01分数规划+树形DP
$ \color{#0066ff}{ 题目描述 }$ 某地方有N个工厂,有N-1条路连接它们,且它们两两都可达.每个工厂都有一个产量值和一个污染值.现在工厂要进行规划,拆除其中的M个工厂,使得剩下的工 ...
- [开源JVM] yvm - 自制Java虚拟机
中文 | English | | | YVM是用C++写的一个Java虚拟机,现在支持Java大部分功能,以及一个基于标记清除算法的并发垃圾回收器. 不过还有很多bug等待修复. 感兴趣的朋友pull ...
- ReactNative之坑:停在gradle一直出点
问题: 初次安装好React Native 环境后,运行项目,会停留在下载 gradle 的界面一直出点 原因: 下载gradle一直不成功 解决方案: 可以根据提示的版本信息,手动下载,放在目录中, ...
- 认识CSS中布局之文档流、浮动、定位以及叠放次序
前端之HTML,CSS(七) CSS CSS布局的核心就是盒子的摆放,即CSS定位.而CSS中定位机制分为:普通流(nomal flow).浮动(float).定位(position). 普通流 普通 ...