C#记事本项目开发,一个可以实现批量操作的记事本!【附源码】
基于C#开发的一款记事本软件,包括记事本文件的新建、打开、读取、保存、文本的加粗、倾斜、字体、字号,记事本的批量操作等。
Hello!大灰狼又来和大家分享值得学习的C#开发项目了,今天和大家分享一个大家应该都比较熟悉的开发项目—“记事本”。
很多小伙伴可能也都使用过记事本来记录一些自己比较重要或者容易忘记的事情,但是你知道它是怎么开发出来的嘛?
同样和之前大灰狼和大家分享的计算器项目一样,记事本项目也可以使用很多不同的语言开发,今天大灰狼就先和大家介绍一下使用C#开发记事本的思路和流程。
同时对于Java和C#在GUI编程上相同和不同之处,小伙伴可以看我之前的这篇文章“Java交互界面实现计算器开发设计【附函数源码】”,
好了,废话不多说,直接上教程。
C#的记事本开发需要我们定义两个窗体,也就是一个承载所有记事本的父窗体,一个具有记事本基本功能的子窗体。
.
记事本子窗体
所以我们首先来聊一下具有记事本基本功能的子窗体的开发。
在C#的窗体应用中,我们可以直接对界面进行控件布局,不需要使用代码定义控件,在这一点上C#的窗体应用开发是很不错的。
那么在记事本应用中,我们应该添加在窗体中的控件应该有,文件的新建、打开、保存,以及字体的样式、字号、是否加粗倾斜这些基本的记事本控件。同时当然还需要记事本的编辑文本框,方便我们对内容的修改和输入。
了解了这些基本的控件之后,就是我们对每一个控件所绑定的函数的书写了,
获取系统字体函数
首先我们是在设置字体时的需要获取到系统的所有字体样式,
通过以下函数实现:
//获取系统字体
private void FormSon_Load(object sender, EventArgs e)
{
//窗体加载时要加载的字体
InstalledFontCollection MyFontStaly = new InstalledFontCollection();
//获取InstalledFontCollection对象的数据
FontFamily[] ff = MyFontStaly.Families;
//定义一个新的ArrayList数组列表
ArrayList list = new ArrayList();
//获取到字体数组的列表的长度
int count = ff.Length;
for (int i = 0; i < count; i++)
{
//获取到字体数组的字体的名字
string FontName = ff[i].Name;
//将字体保存在字体控件中
toolStripComboBox_fonyStaly.Items.Add(FontName);
}
}
字体空间函数
在获取到系统可以设置的所有字体样式之后,就是我们在点击字体时,字体变化的控件了,在这里我们需要在改变字体索引的控件中进行设置,
函数如下:
//改变字体的索引
private void toolStripComboBox_fonyStaly_SelectedIndexChanged(object sender, EventArgs e)
{
//接收当前字体框的文本
string fontname = toolStripComboBox_fonyStaly.Text;
//接收当前字号框的数值
float fontsize = float.Parse(toolStripComboBox_fontSize.Text);
textBox_Text.Font = new Font(fontname, fontsize);
}
字号空间函数
设置完成字体控件的属性之后,就是字号属性了,与设置字体控件的思路相似,我们同样需要先获取到改变字号的索引,函数如下:
//改变字号的索引
private void toolStripComboBox_fontSize_SelectedIndexChanged(object sender, EventArgs e)
{
//接收当前字体框的文本
string fontname = toolStripComboBox_fonyStaly.Text;
//接收当前字号框的数值
float fontsize = float.Parse(toolStripComboBox_fontSize.Text);
textBox_Text.Font = new Font(fontname, fontsize);
}
在字号发生变化时,我们需要将文本框中的内容的字号进行改变,这个时候就需要我们在相应的函数中进行设置:
//当字号发生改变时
private void toolStripComboBox_fontSize_TextChanged(object sender, EventArgs e)
{
//接收当前字体框的文本
string fontname = toolStripComboBox_fonyStaly.Text;
//接收当前字号框的数值
float fontsize = float.Parse(toolStripComboBox_fontSize.Text);
textBox_Text.Font = new Font(fontname, fontsize);
}
加粗控件函数
//加粗按钮
private void toolStripButton_over_Click(object sender, EventArgs e)
{
//点击加粗按钮,字体加粗,加粗是点击按钮取消加粗
//如果目前处于未加粗状态,点击进行加粗
if (textBox_Text.Font.Bold == false)
{
textBox_Text.Font = new Font(textBox_Text.Font, FontStyle.Bold);
}
//如果当前处于加粗状态,点击取消加粗
else
{
textBox_Text.Font = new Font(textBox_Text.Font, FontStyle.Regular);
}
}
倾斜控件函数
//倾斜按钮
private void toolStripButton_slanr_Click(object sender, EventArgs e)
{
if (textBox_Text.Font.Italic == false)
{
textBox_Text.Font = new Font(textBox_Text.Font, FontStyle.Italic);
}
else
{
textBox_Text.Font = new Font(textBox_Text.Font, FontStyle.Regular);
}
}
保存控件函数
在做保存控件的时候,我们需要考虑到一点,就是我们所保存的文件信息,是否是新建的文本框,如我们是新建的记事本,则在保存时则需要选择保存路径和文件名,如果我们是对原有的文件进行二次编辑,则我们在点击保存按钮时只需要进行保存即可,无需重新选择文件的保存路径。
函数代码如下:
//保存按钮
private void toolStripButton_save_Click(object sender, EventArgs e)
{
//创建一个筛选器
saveFileDialog1.Filter = ("文本文档(*,txt)|*.txt");
// 判断如果当前文本框不为空,则进行保存
if (textBox_Text.Text.Trim() != "")
{
//如果记事本文件是新的,则选择路径保存
if (this.Text == "记事本")
{
//保存文件到用户的指定目录下
//判断用户是保存还是取消
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
//获取用户选择的文件及路径
string path = saveFileDialog1.FileName;
//保存文件到指定路径
StreamWriter sw = new StreamWriter(path, false);
sw.WriteLine(textBox_Text.Text.Trim());
//在窗体上方显示路径
this.Text = path;
//清空缓存
sw.Flush();
sw.Close();
}
}
//如果是已经打开的文件,则直接进行保存
else
{
//保存文件到用户的指定目录下
//获取用户选择的文件及路径
string path = this.Text;
//保存文件到指定路径
StreamWriter sw = new StreamWriter(path, false);
sw.WriteLine(textBox_Text.Text.Trim());
sw.Flush();
sw.Close();
}
}
//如果为空,则进行消息框提示
else
{
MessageBox.Show("当前文本框为空!n不可进行保存!", "警告");
}
}
打开文件控件函数:
在进行文件的打开操作时,我们需要对所打开的文件进行筛选,只要求打开txt格式的文本文件即可。
实现函数如下:
//打开文件
private void toolStripButton_open_Click(object sender, EventArgs e)
{
//筛选一个打开文件
openFileDialog1.Filter = ("文本文档(*,txt)|*.txt");
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string path = openFileDialog1.FileName;
StreamReader sr = new StreamReader(path, Encoding.UTF8);
string text = sr.ReadToEnd();
//在文本框上方显示路径
this.Text = path;
textBox_Text.Text = text;
sr.Close();
}
}
新建文本控件函数
在点击新建文本之后,我们需要将原来编辑的内容进行清空并且重新建立编辑。
函数如下:
//新建文本
private void toolStripButton1_Click(object sender, EventArgs e)
{
this.Text = "记事本";
textBox_Text.Text = "";
toolStripTextBox1.Text = "";
}
窗体关闭控件函数
在我们的文本被修改之后,如果用户点击关闭按钮,这个时候就需要对用户进行提示,如果用户选择关闭,则进行记事本文本框的关闭操作,并且不会进行保存,如果用户点击了否,则重新回到编辑页面进行编辑。
函数如下:
///窗体关闭时
private void FormSon_FormClosing(object sender, FormClosingEventArgs e)
{
//如果文件已经被修改,则进行提示
if (toolStripTextBox1.Text == "文本已修改")
{
DialogResult dr = MessageBox.Show("文本已经修改!是否继续退出?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
//如果用户选择是,则退出
if (dr == DialogResult.Yes)
{
this.Dispose();
}
//如果用户选择否,则返回页面
else
{
e.Cancel = true;
}
}
}
在以上这些函数完成之后,我们的记事本文本编辑窗口就完成了,看一下效果:
.
主控页面父窗体
接下来就是承载记事本编辑窗口的父窗体了。
在父窗体中需要包括的控件有记事本的新建、关闭、全部关闭、退出等。
新建记事本
设置新建记事本控件属性的时候,我们只需要调用我们刚刚完成的记事本子窗体即可。
函数如下:
//新建
private void ToolStripMenuItem_newfile_Click(object sender, EventArgs e)
{
//定义一个变量接收子窗体
FormSon son = new FormSon();
//定义子窗体的父窗体
son.MdiParent = this;
//显示子窗体
son.Show();
}
关闭窗体
关闭窗体时,我们所关闭的是当前处于最前方的活跃的窗体。
函数如下:
//关闭窗体
private void ToolStripMenuItem_closefile_Click(object sender, EventArgs e)
{
//接收当前窗体
Form form = this.ActiveMdiChild;
//关闭当前窗体
form.Close();
}
关闭全部窗体
点击关闭全部窗体时,我们会将已经打开的所有记事本窗体全部关闭。
函数如下:
//关闭全部窗体
private void ToolStripMenuItem_closeall_Click(object sender, EventArgs e)
{
//循环遍历当前已经打开的所有窗体的集合
foreach (Form form in this.MdiChildren)
{
Form frm = this.ActiveMdiChild;
frm.Close();
}
}
退出控件
最后一个需要设置的是退出,点击时会将记事本窗体整体关闭,因此,我们只需要将当前打开的窗体关闭即可。
函数如下:
//退出
private void ToolStripMenuItem_quit_Click(object sender, EventArgs e)
{
this.Close();
}
设置完父窗体之后,记事本的整体开发就完成了,现在看一下整体效果。
觉得不错记得点赞关注大灰狼哟!
可以点击此处下载“开发源码”,或者关注大灰狼的微信公众号 “灰狼洞主” 回复“C#记事本”即可获取完整源码!
大灰狼陪你一起进步!
- 如何使用HAProxy实现HiveServer2负载均衡
- 机器学习之决策树算法
- 如何使用HAProxy实现Impala的负载均衡
- 解读GEO数据存放规律及下载,一文就够
- 从GEO数据库下载得到表达矩阵 一文就够
- 机器学习各类算法比较
- Kerberos环境下删除ZooKeeper服务注册信息问题分析
- 根据分组信息做差异分析- 这个一文不够的
- 如何使用Cloudera Manager启用YARN的HA
- 如何使用java代码通过JDBC连接Hive(附github源码)
- 差异分析得到的结果注释一文就够
- 如何使用Cloudera Manager禁用HDFS HA
- 转录组表达数据分析的一些可视化
- 如何使用java代码通过JDBC连接Impala(附Github源码)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android如何通过命令行操作Sqlite3数据库的方法
- Android实现沉浸式状态栏功能
- PHP对验证码的认证过程
- Android实现图片加载进度提示
- android shape实现阴影或模糊边效果
- Spring Data JPA主键采用UUID策略
- Android自定义控件之水平圆点加载进度条
- Android屏幕旋转之横屏竖屏切换的实现
- Android Studio连接SQLite数据库的登录注册实现
- Android 获取 usb 权限的两种方法
- Android实现两圆点之间来回移动加载进度
- Android使用第三方库实现日期选择器
- Android Activity向右滑动返回
- 大多数人都不懂的搜索引擎技巧,掌握这几点,提升你的工作效率
- 如何使用Flutter实现58同城中的加载动画详解