WEEK9-仿制WINOWS记事本

573 阅读5分钟

功能说明

该记事本除实现了Windows自带的记事本的部分功能外,还可以任意更改字体的字体类型、大小和颜色,并在状态栏中显示时间。

为了方便用户的操作,还在程序的窗体上放置了一个工具栏。

源码展示

界面设计等操作参考:C#+Winform记事本程序

TOTAL.jpg

image.png

1. 设置标志位

bool b = false; // 判断文件是新建的还是从磁盘打开的
// true表示文件是从磁盘打开的,false表示文件是新建的,默认值为false

bool s = true; // 判断文件件是否被保存
// true表示文件是已经被保存了,false表示文件未被保存,默认值为true

2. 菜单

2.1 文件

SaveFileDialog & OpenFileDialog & RichTextBox提供的方法

2.1.1 新建

image.png

// 新建
        // 当前文件从磁盘打开|非空,则选择是否保存
            // 保存
                // 若文件从磁盘打开并且修改了其内容,则按打开路径保存
                // 若文件为新建并且非空,则在SaveFileDialog选择路径后保存
                // 置状态为保存
            // 不保存
                // 清空RichTextBox的Text,置状态为新建
        private void tsmiNew_Click(object sender, EventArgs e)
        {
            if (b == true || rtxtNotepad.Text.Trim() != "")
            {
                if (s == false)
                {
                    string result;
                    result =
                        MessageBox
                            .Show("文件尚未保存,是否保存?",
                            "保存文件",
                            MessageBoxButtons.YesNoCancel)
                            .ToString();
                    switch (result)
                    {
                        case "Yes":
                            if (b == true)
                            {
                                rtxtNotepad.SaveFile(odlgNotepad.FileName);
                            }
                            else if (sdlgNotepad.ShowDialog() == DialogResult.OK
                            )
                            {
                                rtxtNotepad.SaveFile(sdlgNotepad.FileName);
                            }
                            s = true;
                            rtxtNotepad.Text = "";
                            break;
                        case "No":
                            b = false;
                            rtxtNotepad.Text = "";
                            break;
                    }
                }
            }
        }

2.1.2 打开

前一部分代码同“新建”。

// 打开
        // 调用新建方法
        // 利用OpenFileDialog选择打开的文件
        // 置状态为由磁盘打开 & 保存
        private void tsmiOpen_Click(object sender, EventArgs e)
        {
            tsmiNew_Click (sender, e);
            odlgNotepad.RestoreDirectory = true;
            if (
                (odlgNotepad.ShowDialog() == DialogResult.OK) &&
                odlgNotepad.FileName != ""
            )
            {
                rtxtNotepad.LoadFile(odlgNotepad.FileName);
                b = true;
            }
            s = true;
        }
2.1.3 保存
// 保存
        // 若文件从磁盘打开并且修改了其内容,则直接保存
        // 若文件为新建并且非空,则在SaveFileDialog选择路径后保存,置状态为由磁盘打开
        // 置状态为保存
        private void tsmiSave_Click(object sender, EventArgs e)
        {
            if (b == true && rtxtNotepad.Modified == true)
            {
                rtxtNotepad.SaveFile(odlgNotepad.FileName);
                s = true;
            }
            else if (
                b == false &&
                rtxtNotepad.Text.Trim() != "" &&
                sdlgNotepad.ShowDialog() == DialogResult.OK
            )
            {
                rtxtNotepad.SaveFile(sdlgNotepad.FileName);
                s = true;
                b = true;
                odlgNotepad.FileName = sdlgNotepad.FileName;
            }
        }
2.1.4 另存为
// 另存为
        // 在SaveFileDialog选择路径后保存
        // 置状态为保存
        private void tsmiSaveAs_Click(object sender, EventArgs e)
        {
            if (sdlgNotepad.ShowDialog() == DialogResult.OK)
            {
                rtxtNotepad.SaveFile(sdlgNotepad.FileName);
                s = true;
            }
        }
2.1.5 退出
// 退出
        private void tsmiClose_Click(object sender, EventArgs e)
        {
            tsmiNew_Click(sender, e);
            Application.Exit();
        }

2.2 编辑

均使用RichTextBox提供的方法

image.png

2.2.1 撤销
// 撤销
        private void tsmiUndo_Click(object sender, EventArgs e)
        {
            rtxtNotepad.Undo();
        }
2.2.2 复制
// 复制
        private void tsmiCopy_Click(object sender, EventArgs e)
        {
            rtxtNotepad.Copy();
        }
2.2.3 剪切
// 剪切
        private void tsmiCut_Click(object sender, EventArgs e)
        {
            rtxtNotepad.Cut();
        }
2.2.4 粘贴
// 粘贴
        private void tsmiPaste_Click(object sender, EventArgs e)
        {
            rtxtNotepad.Paste();
        }
2.2.5 全选
// 全选
        private void tsmiSelectAll_Click(object sender, EventArgs e)
        {
            rtxtNotepad.SelectAll();
        }
2.2.6 日期
// 利用System.DateTime.Now,获取当前日期时间
        private void tsmiDate_Click(object sender, EventArgs e)
        {
            rtxtNotepad.AppendText(System.DateTime.Now.ToString());
        }

2.3 格式

image.png

2.3.1 自动换行
// 自动换行
        // 依据Checked属性,更改RichTextBox的WordWrap属性
        private void tsmiAuto_Click(object sender, EventArgs e)
        {
            if (tsmiAuto.Checked == false)
            {
                tsmiAuto.Checked = true;
                rtxtNotepad.WordWrap = true;
            }
            else
            {
                tsmiAuto.Checked = false;
                rtxtNotepad.WordWrap = false;
            }
        }
2.3.2 字体

FontDialog

// 字体-FontDialog
        // 依据FontDialog的Color和Font属性,
        // 更改RichTextBox的SelectionColor和SelectionFont属性
        private void tsmiFont_Click(object sender, EventArgs e)
        {
            fdlgNotepad.ShowColor = true;
            if (fdlgNotepad.ShowDialog() == DialogResult.OK)
            {
                rtxtNotepad.SelectionColor = fdlgNotepad.Color;
                rtxtNotepad.SelectionFont = fdlgNotepad.Font;
            }
        }

2.4 查看

image.png

2.4.1 工具栏
// 工具栏显示隐藏
        // 依据Checked属性,更改ToolStrip的Visible属性
        // 修改RichTextBox的Location和Height属性
        private void tsmiToolStrip_Click(object sender, EventArgs e)
        {
            Point point;
            if (tsmiToolStrip.Checked == true)
            {
                // 隐藏工具栏时,把坐标设为(0,24),因为菜单的高度为24
                point = new Point(0, 24);
                tsmiToolStrip.Checked = false;
                tlsNotepad.Visible = false;
                // 设置多格式文本框左上角位置
                rtxtNotepad.Location = point;
                // 隐藏工具栏后,增加文本框高度
                rtxtNotepad.Height += tlsNotepad.Height;
            }
            else
            {
                // 显示工具栏时,多格式文本框左上角位置的位置为(0,49),
                // 因为工具栏的高度为25,加上菜单的高度24后为49
                point = new Point(0, 49);
                tsmiToolStrip.Checked = true;
                tlsNotepad.Visible = true;
                rtxtNotepad.Location = point;
                rtxtNotepad.Height -= tlsNotepad.Height;
            }
        }
2.4.2 状态栏

StatusStrip在RichTextBox下方,不影响RichTextBox的Location属性(左上角位置)。

// 状态栏显示隐藏
        // 依据Checked属性,更改StatusStrip的Visible属性
        // 修改RichTextBox的Height
        // StatusStrip在RichTextBox下方,不影响RichTextBox的Location属性(左上角位置)
        private void tsmiStatusStrip_Click(object sender, EventArgs e)
        {
            if (tsmiStatusStrip.Checked == true)
            {
                tsmiStatusStrip.Checked = false;
                stsNotepad.Visible = false;
                rtxtNotepad.Height += stsNotepad.Height;
            }
            else
            {
                tsmiStatusStrip.Checked = true;
                stsNotepad.Visible = true;
                rtxtNotepad.Height -= stsNotepad.Height;
            }
        }

2.5 帮助

image.png

2.5.1 关于记事本
2.5.1.1 子窗体

选用win10自带记事本的帮助链接。

image.png

// 关闭帮助信息窗体
        private void btnOK_Click(object sender, EventArgs e)
        {
            this.Close();
        }
// 打开帮助链接(选用win10自带记事本的帮助链接)
        private void LinkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("https://cn.bing.com/search?q=get+help+with+notepad+in+windows+10&filters=guid:%224466414-en-dia%22%20lang:%22en%22&form=T00032&ocid=HelpPane-BingIA");
        }
2.5.1.2 父窗体
// 显示帮助信息窗体
        private void tsmiAbout_Click(object sender, EventArgs e)
        {
            frmAbout ob_FrmAbout = new frmAbout();
            ob_FrmAbout.Show();
        }

2.6 工具栏

索引位由0开始,且分隔符也占索引位。

// 由工具栏点击项索引号,调用菜单中“编辑”下的对应方法
        private void tlsNotepad_ItemClicked(
            object sender,
            ToolStripItemClickedEventArgs e
        )
        {
            int n;

            n = tlsNotepad.Items.IndexOf(e.ClickedItem);
            switch (n)
            {
                case 0:
                    tsmiSave_Click (sender, e);
                    break;
                case 1:
                    tsmiOpen_Click (sender, e);
                    break;
                case 2:
                    tsmiSave_Click (sender, e);
                    break;
                case 4:
                    tsmiCopy_Click (sender, e);
                    break;
                case 5:
                    tsmiCut_Click (sender, e);
                    break;
                case 6:
                    tsmiPaste_Click (sender, e);
                    break;
                case 8:
                    tsmiAbout_Click (sender, e);
                    break;
            }
        }

2.7 事件触发

2.7.1 RichTextBox控件的TextChanged事件

// RichTextBox控件的TextChanged事件
        // 文本被修改,置状态为未保存
        private void rtxNotepad_TextChanged(object sender, EventArgs e)
        {
            s = false;
        }

2.7.2 Form控件的SizeChanged事件

Label的AutoSize属性须置False,否则无法修改Width。

// Form控件的SizeChanged事件
        // 窗体大小改变时,调节状态栏上标签宽度
        // Label的AutoSize属性须置False
        private void frmNotepad_SizeChanged(object sender, EventArgs e)
        {
            tssLbl1.Width = Width / 2;
            tssLbl2.Width = Width / 3;
        }

2.7.3 Timer控件的Tick事件

Interval属性单位为毫秒。

// Timer控件的Tick事件
        // 利用System.DateTime.Now,每秒刷新状态栏时间
        // 置Interval属性(单位:ms)为1000
        private void tmrNotepad_Tick(object sender, EventArgs e)
        {
            tssLbl2.Text = System.DateTime.Now.ToString();
        }

功能测试

image.png

文件

image.png

编辑

image.png

image.png

格式

image.png

查看

image.png

帮助

image.png

窗体大小改变

image.png

image.png

心得体会

  • 通过本次作业,体会到了在软件设计中需求分析的重要性,并对之前学过的“事件”有了更深的认识,也感受到了合理命名对增加可读性的作用(匈牙利命名法)。

.cs 类文件。源代码都写在这里,主要就看这里的代码。

.resx 资源文件,存放资源。

.csproj C#项目文件,用VS打开这个文件就可以直接打开这个项目,自动生成。

.csproj.user 是一个配置文件,自动生成,会记录项目生成路径、项目启动程序等信息。

.Designer.cs 设计文件,自动生成,对窗体上的控件做初始化工作(在函数InitializeComponent()中)。

.aspx 是网页文件,HTML代码写在这里面。

  • 本程序在仍有一定局限性:未实现windows自带记事本中的查找替换等功能;用默认工具栏代替了右键菜单,不够方便;提供的文档在退出程序前未提示是否保存(在Application.Exit()前调用tsmiNew_Click(sender, e)即可实现)。

  • 遇到的困难:

  1. 菜单的窗体设计部分比较繁琐;

  2. 窗体大小改变调节状态栏上标签宽度时,Label的AutoSize属性须置False,否则无法修改Width;

  3. 理清保存操作的判断条件及两个标志位的设立(见代码注释)。

Repository

Giteee