目录
实验:目的
本章介绍如何使用Visual C# 2019设计一个Windows应用程序——记事本,通过本章的学习,可以进一步掌握MenuStrip(菜单)、ToolStrip(工具栏)、RichTextBox(高级文本框)和StatusStrip(状态栏控件)等控件的使用,以及如何使用CommonDialog(公共对话框)实现对文本的存取、格式设置等操作。(说明:所有代码必须在英文状态下使用!)
实验步骤
1.界面设计
1.创建项目
选择 模版 → Visual C# → windows→ windows窗体应用程序 在下面的名称写Notepad
2.按照表格设置剩窗体属性
控件类型 | 控件名称 | 属性 | 设置结果 |
Form | Form1 | Name | frmNotepad |
Text | 记事本 | ||
StartPosition(起始位置) | CenterScreen(中央屏幕) | ||
Size | 600, 450 |
3.MenuStrip(菜单控件)
①:
单击窗体左边会出现工具箱→ 找到menustrip →拖动到窗体中
②:
单击 输入【文件(F)】、【编辑(E)】、【格式(O)】、【查看(V)】和【帮助(H)】如图所示
③:
设置【文件(F)】、【编辑(E)】、【格式(O)】、【查看(V)】和【帮助(H)】的属性
单击【文件(F)】、【编辑(E)】、【格式(O)】、【查看(V)】和【帮助(H)】找到对应的属性窗口,按照以下表格进行设置
Text属性 | Name属性 | ShortcutKeys属性 (快捷键) | ShowShortcutKeys属性 |
文件(&F) | tsmiFile | None | - |
新建(&N) | tsmiNew | Ctrl+N | True |
打开(&O) | tsmiOpen | Ctrl+O | True |
保存(&S) | tsmiSave | Ctrl+S | True |
另存为(&A) | tsmiSaveAs | None | - |
分隔符(用“-”来分隔) | |||
退出(&X) | tsmiClose | None | - |
Text属性 | Name属性 | ShortcutKeys属性 | ShowShortcutKeys属性 | |||||
编辑(&E) | tsmiEdit | None | - | |||||
撤销(&U) | tsmiUndo | Ctrl+Z | True | |||||
分隔符 | ||||||||
复制(&C) | tsmiCopy | Ctrl+C | True | |||||
剪切(&T) | tsmiCut | Ctrl+X | True | |||||
粘贴(&P) | tsmiPaste | Ctrl+V | True | |||||
分隔符 | ||||||||
全选(&A) | tsmiSelectAll | Ctrl+A | True | |||||
日期(&D) | tsmiDate | F5 | True | |||||
Text属性 | Name属性 | Check属性 |
| |||||
格式(&O) | tsmiFormat | False |
| |||||
自动换行(&W) | tsmiAuto | True |
| |||||
字体(&F) | tsmiFont | False |
| |||||
Text属性 | Name属性 | Checked属性 |
| |||||
查看(&V) | tsmiView | False |
| |||||
工具栏(&T) | tsmiToolStrip | True |
| |||||
状态栏(&S) | tsmiStatusStrip | True |
| |||||
|
|
|
| |||||
Text属性 | Name属性 |
| ||||||
帮助(&H) | tsmiHelp |
| ||||||
关于记事本(&A) | tsmiAbout |
|
4.ToolStrip(工具栏控件)
①:
单击窗体左边会出现工具箱→ 找到“ToolStrip” →拖动到窗体中
单击工具栏→右下角属性→修改Name属性为“tlsNotepad”
②:
右击工具栏→ 插入标准项 出现如图所示
右击工具栏→ 编辑项 可以看到我们的按钮成员 在这里我们可以删除或者增加,为了新手学习,我们只设置几个简单的功能(新建,打开,保存,剪切,粘贴,复制)。其它我们不再设置。
③:
为了看起来直观,这个我们不更改它们的Name属性了,接下来根据程序本身的需要,对添加的标准工具子项进行增加和删除,在设置好各子项的属性即可。
5.RichTextBox(多格式文本框控件)。
①:
单击窗体左边会出现工具箱→ 找到“RichTextBox” →拖动到窗体中
单击工具栏→右下角属性→修改Name属性为“rtxtNotepad”
②:
Anchor属性选择“Top,Bottom,Left,Right”,这样当窗体大小改变时,RichTextBox控件的大小也会跟着改变,如图2.1所示
6.StatusStrip(状态栏控件)
①:
添加StatusStrip控件,将其Name属性设为“stsNotepad”,将Dock属性设为“Bottom”再将Anchor属性设为“Bottom,Left,Right”。然后单击右边的
按钮,打开【项集合编辑器】对话框,如图所示。
下拉列表中保留默认的选择“StatusLabel”,然后单击【添加】按钮,依次添加2个StatusLabel,并分别命名为“tssLbl1”和“tssLbl2”,再将tssLbl1的Text属性设为“就绪”, tssLbl2的Text属性设为“显示日期、时间”。
②:
7.其它控件
1.OpenFileDialog(打开对话框)。
从工具箱中找到OpenFileDialog直接拖入窗体中 单击属性
当用户单击记事本的【文件】→【打开】菜单项时,使用打开对话框OpenFileDialog打开文件。OpenFileDialog控件的Name属性为“odlgNotepad”,Filter属性设为“所有文件|*.*”。我用的方法理论上不需要考虑格式
2.SaveFileDialog(保存对话框)。
从工具箱中找到SaveFileDialog直接拖入窗体中 单击属性
当用户单击记事本的【文件】→【保存】(或【另存为】)菜单项时,使用保存对话框SaveFileDialog保存文件。SaveFileDialog控件的Name属性为“sdlgNotepad”,FileName属性改为“无标题”,Filter属性设为“RTF文件|*.txt”。
3.FontDialog(字体对话框)。
从工具箱中找到FontDialog直接拖入窗体中 单击属性
当用户单击记事本的【格式】→【字体】菜单项时,使用字体对话框FontDialog设置文本字体。FontDialog控件的Name属性为“fdlgNotepad”。
4.Timer(计时器控件)。
从工具箱中找到Timer直接拖入窗体中 单击属性
本章介绍的记事本在状态栏中显示了时钟,这就需要使用一个Timer控件来实现。Timer控件的Name属性设为“tmrNotepad”,Enabled(激活的可行的)属性设为“True”,Interval(间隔,间距,幕间时间)属性设为“1000”,表示1秒种触发一次Tick事件,即1秒钟改变一次时钟。
结果如图:
2.代码实现
先行说明:
//*************************************************************************
/* 布尔变量b用于判断文件是新建的还是从磁盘打开的,
true表示文件是从磁盘打开的,false表示文件是新建的,默认值为false*/
bool b = false;
/* 布尔变量s用于判断文件件是否被保存,
true表示文件是已经被保存了,false表示文件未被保存,默认值为true*/
bool s = true;
//*************************************************************************
(1) 多格式文本框代码(RichTextBox)
private void rtxtNotepad_TextChanged(object sender, EventArgs e)
{
// 文本被修改后,设置s为false,表示文件未保存
s = false;
}
(2) 菜单代码
1. 【文件(F)】菜单
保存函数
//保存函数
public void baochun(string name)
{
FileStream sd = null;
try
{
sd = new FileStream(name, FileMode.Truncate, FileAccess.Write);
string v = rtxtNotepad.Text;
byte[] buf = Encoding.Default.GetBytes(v);
sd.Write(buf, 0, buf.Length);
}
catch (Exception ex)
{
Trace.Write("清空日志文件失败:" + ex.Message);
}
finally
{
if (sd != null)
{
sd.Close();
sd.Dispose();
}
}
}
打开函数
//打开文件函数
public void dakai(string name)
{
FileStream sd = null;
try
{
sd = new FileStream(name, FileMode.OpenOrCreate, FileAccess.Read);
this.Text = name;
byte[] buf = new byte[1024 * 1024*4];
rtxtNotepad.Clear();
int r;
do
{
r = sd.Read(buf, 0, buf.Length);
string v = Encoding.Default.GetString(buf, 0, r);
rtxtNotepad.Text += v;//打开代码语句
} while (r != 0);
}
catch(Exception ex)
{
Trace.Write("打开文件失败:" + ex.Message);
}
finally
{
if (sd != null)
{
sd.Close();
sd.Dispose();
}
}
}
(1) 【新建(N)】菜单项
//新建
private void tsmiNew_Click(object sender, EventArgs e)
{
if (b == true || rtxtNotepad.Text.Trim() != "")
{
//文件未保存
if (s == false)
{
string result
= MessageBox.Show("文件尚未保存,是否保存?", "保存文件", MessageBoxButtons.YesNoCancel).ToString();
switch (result)
{
case "Yes":
//是打开的磁盘文件
if (b == true)
{
baochun(odlgNotepad.FileName);
}
else if (sdlgNotepad.ShowDialog() == DialogResult.OK)
{
baochun(sdlgNotepad.FileName);
}
s = true;
break;
case "No":
b =false;
break;
}
}
}
rtxtNotepad.Clear();
this.Text = "记事本";
}
(2) 【打开(O)】菜单项
//打开
private void tsmiOpen_Click(object sender, EventArgs e)
{
if (b == true || rtxtNotepad.Text.Trim() != "")
{
//原来的是否保存
if (s == false)
{
string result
= MessageBox.Show("文件尚未保存,是否保存?",
"保存文件", MessageBoxButtons.YesNoCancel).ToString();
switch (result)
{
case "Yes":
if (b == true)
{
baochun(odlgNotepad.FileName);
}
else if (sdlgNotepad.ShowDialog() == DialogResult.OK)
{
baochun(sdlgNotepad.FileName);
}
s = true;
break;
case "No":
b = false;
rtxtNotepad.Text = "";
break;
}
}
}
//选定当前目录
odlgNotepad.RestoreDirectory = true;
if ((odlgNotepad.ShowDialog() == DialogResult.OK) && odlgNotepad.FileName != "")
{
dakai(odlgNotepad.FileName);
b = true;
}
s = true;
}
(3) 【保存(S)】菜单项
//保存
private void tsmiSave_Click(object sender, EventArgs e)
{
// 若文件从磁盘打开并且修改了其内容
if (b == true && rtxtNotepad.Modified == true)
{
s = true;
}
else if (b == false && rtxtNotepad.Text.Trim() != "" &&
sdlgNotepad.ShowDialog() == DialogResult.OK)
{
// RichTextBoxStreamType.PlainText
s = true;
b = true;
odlgNotepad.FileName = sdlgNotepad.FileName;
}
baochun(odlgNotepad.FileName);
this.Text = odlgNotepad.FileName;
}
(4) 【另存为(A)】菜单项
private void tsmiSaveA_Click(object sender, EventArgs e)
{
if (sdlgNotepad.ShowDialog() == DialogResult.OK)
{
FileStream sd =
sd = new FileStream(sdlgNotepad.FileName, FileMode.OpenOrCreate, FileAccess.Write);
string v = rtxtNotepad.Text;
byte[] buf = Encoding.Default.GetBytes(v);
sd.Write(buf, 0, buf.Length);
sd.Close();
sd.Dispose();
s = true;
}
}
(5) 【退出(X)】菜单项
private void tsmiClose_Click(object sender, EventArgs e)
{
Application.Exit();
}
(3) 【编辑(E)】菜单
private void 撤销UToolStripMenuItem_Click(object sender, EventArgs e)
{
rtxtNotepad.Undo();
}
private void 复制CToolStripMenuItem_Click(object sender, EventArgs e)
{
rtxtNotepad.Copy();
}
private void 剪切XToolStripMenuItem_Click(object sender, EventArgs e)
{
rtxtNotepad.Cut();
}
private void 粘贴VToolStripMenuItem_Click(object sender, EventArgs e)
{
rtxtNotepad.Paste();
}
private void 全选AToolStripMenuItem_Click(object sender, EventArgs e)
{
rtxtNotepad.SelectAll();
}
private void 日期DToolStripMenuItem_Click(object sender, EventArgs e)
{
rtxtNotepad.AppendText(System.DateTime.Now.ToString());
}
(4) 【格式(O)】菜单
(1) 【自动换行(W)】菜单项
private void 自动换行WToolStripMenuItem_Click(object sender, EventArgs e)
{
if (自动换行WToolStripMenuItem.Checked == false)
{
自动换行WToolStripMenuItem.Checked = true; // 选中该菜单项
rtxtNotepad.WordWrap = true; // 设置为自动换行
}
else
{
自动换行WToolStripMenuItem.Checked = false;
rtxtNotepad.WordWrap = false;
}
}
(2) 【字体(F)】菜单项
private void 字体FToolStripMenuItem_Click(object sender, EventArgs e)
{
fdlgNotepad.ShowColor = true;
if (fdlgNotepad.ShowDialog() == DialogResult.OK)
{
rtxtNotepad.SelectionColor = fdlgNotepad.Color;
rtxtNotepad.SelectionFont = fdlgNotepad.Font;
}
}
(5) 【查看(V)】菜单
(1) 【工具栏(T)】菜单项
private void 工具栏TToolStripMenuItem_Click(object sender, EventArgs e)
{
Point point;
if (工具栏TToolStripMenuItem.Checked == true)
{
// 隐藏工具栏时,把坐标设为(0,20),因为菜单的高度为24
point = new Point(0, 20);
工具栏TToolStripMenuItem.Checked = false;
tlsNotepad.Visible = false;
// 设置多格式文本框左上角位置
rtxtNotepad.Location = point;
// 隐藏工具栏后,增加文本框高度
rtxtNotepad.Height += tlsNotepad.Height;
}
else
{
// 显示工具栏
point = new Point(0, 40);
工具栏TToolStripMenuItem.Checked = true;
tlsNotepad.Visible = true;
rtxtNotepad.Location = point;
rtxtNotepad.Height -= tlsNotepad.Height;
}
}
(6) 【帮助(H)】菜单
private void 关于记事本AToolStripMenuItem_Click(object sender, EventArgs e)
{
frmAbout ob_FrmAbout = new frmAbout();
ob_FrmAbout.Show();
}
(7) 工具栏代码
private void tlsNotepad_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
int n;
// 变量n用来接收按下按钮的索引号从0开始
n = tlsNotepad.Items.IndexOf(e.ClickedItem);
switch (n)
{
case 0:
tsmiNew_Click(sender, e);
break;
case 1:
tsmiOpen_Click(sender, e);
break;
case 2:
tsmiSaveA_Click(sender, e);
break;
/*case 3:
tsmiCopy_Click(sender, e);
break;*/ // 我们不用case3
case 4:
剪切XToolStripMenuItem_Click(sender, e);
break;
case 5:
复制CToolStripMenuItem_Click(sender, e);
break;
case 6:
粘贴VToolStripMenuItem_Click(sender, e);
break;
}
}
(8)计时器代码
private void tmrNotepad_Tick(object sender, EventArgs e)
{
toolStripStatusLabel1.Text = System.DateTime.Now.ToString();
}
设计结束!
代码地址:Notepad: c#记事本
Notepad: c#记事本https://gitee.com/chhenming/notepad