简单文档编辑器

一、学习目标

l  参考系统的写字板功能,编写一个小型的文字编辑工具。

l  该文档编辑器,有以下功能:

①文件操作:新建,打开,保存,另存为,退出;

②编辑操作: 撤销,恢复,复制,剪切,粘贴,全选,清空;

③搜索:查找与替换;

④格式操作: 字体,颜色,粗体,斜体,下划线;

⑤支持快捷键操作

l  界面设计观,操作简便,有工具栏、右键菜单、状态栏。

 

二、设计思路

1)首先,是窗口的设计,一个好的UI界面,用户使用起来会更加方便快捷。把MainForm 的控件设计做好。菜单用MenuStrip,工具栏用ToolStrip,文本编辑框用RichTextBox,

状态栏用statusStrip,右键菜单用contextMenuStrip,保存文件对话框saveFileDialog,打开文件对话框openFileDialog。然后在Visual Studio C# 中把控件相应的属性设置好,比如Dock属性、filter属性、Font属性等。

菜单的图标在网上搜索或者截图。

菜单栏ToolStripMenuItem通过ShortCutKeys属性设置菜单的快捷键。

然后将SearchAndReplaceForm设计好。

 

2)文本的新建,打开,保存,另存为功能实现

首先文本的状态设置有2中,文档是否被修改isChanged和文档是否曾保存在文件中isSaved。

 

新建文件时

        private void 新建ToolStripMenuItem_Click(object sender, EventArgs e)

        {

            AlertSaveFile(); // 提示用户保存文件

            this.txtMain.Clear();//清空文本内容

            this.isSaved = false;

            this.saveStatus.Text = "未保存";

            this.Text = "无标题 ---- Editor";

            this.isChanged = false;

        }

 

private bool AlertSaveFile() // 提示用户保存文件

        {

            if (isChanged) // 表示文档有改动并且未保存

            {

                DialogResult result =

                    MessageBox.Show(this, "存在文件尚未保存,要保存改动吗?", "文本编辑器", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);

                // 保存文档

                if (result == DialogResult.Yes)

                {

                    if (this.isSaved)

                    {

                        this.txtMain.SaveFile(FileName);

                    }

                    else

                    {

                        另存为toolStripMenuItem_Click(null, null);

                    }

                }// 不保存文档

                else if (result == DialogResult.No)

                {

                }// 取消

                else

                {

                    return false; // 表示点击取消

                }

            }

            return true; // 表示点击其他

        }

 

另存为时

private void 另存为toolStripMenuItem_Click(object sender, EventArgs e)

        {

            if (this.saveFileDialog2.ShowDialog() == DialogResult.OK)//保存文件确认

            {

                try

                {

                    FileInfo finfo = new FileInfo(this.saveFileDialog2.FileName);//文件名

                    if (finfo.Extension == ".rtf")//若为rtf格式的文档

                    {

                        this.txtMain.SaveFile(finfo.FullName, RichTextBoxStreamType.RichText);

                    }

                    else//其他情况下的文档

                    {

                        this.txtMain.SaveFile(finfo.FullName, RichTextBoxStreamType.PlainText);

                    }

                    this.FileName = this.saveFileDialog2.FileName;

 

                    this.isSaved = true;//更改保存状态为已保存

                    this.saveStatus.Text = "已保存于" + DateTime.Now.ToShortTimeString();

                    this.isChanged = false;

                    this.Text = this.FileName;

 

文件打开是先要检查当前文本是否已经有改动,若有改动要询问用户是否保存,其他情况类似上面讲的。

文件保存和另存为类似,如果已经保存过了,就直接写入当前文件,如果没有保存过,就调用另存为的功能。

 

3)文本编辑的复制,剪切,粘贴,全选,清空,这些操作的对象都是RichTextBox中的文本,调用相应的函数就可以了。

复制 this.txtMain.Copy();

剪切 this.txtMain.Cut();

粘贴 this.txtMain.Paste();

全选 this.txtMain.SelectAll();

清空 this.txtMain.Text = "";

 

4)查找与替换

初始化是指定父窗口

public SearchAndReplaceForm(MainForm parent)

        {

            InitializeComponent();

            this.parentForm = parent;

        }

文本框的作用范围由默认的private修改为public

public System.Windows.Forms.RichTextBox txtMain;

 

查找功能:SearchText(true);

这个方法,主要判断查找的方向、是否大小写匹配,关键语句是

 //函数完成文本的查找功能,参数表示是否在未找到指定文本时显示消息,返回值为是否找到指定文本

        private bool SearchText(bool isShowFound)

        {

            bool isFound = true;

            if (this.caseCheckBox.Checked)// 表示大小写匹配查找

            {

                if (this.downRadioButton.Checked) // 表示向下查找

                {

                    this.searchPos = this.parentForm.txtMain.Find(this.strSearch, searchPos,this.parentForm.txtMain.Text.Length, RichTextBoxFinds.MatchCase);

                }

                else

                {

                    this.searchPos = this.parentForm.txtMain.Find(this.strSearch, 0,searchPos, RichTextBoxFinds.MatchCase | RichTextBoxFinds.Reverse);

                }

            }

            else

            {

                if (this.downRadioButton.Checked)

                {

                    this.searchPos = this.parentForm.txtMain.Find(this.strSearch, searchPos,this.parentForm.txtMain.Text.Length, RichTextBoxFinds.None);

                }

                else

                {

                    this.searchPos = this.parentForm.txtMain.Find(this.strSearch, 0,searchPos, RichTextBoxFinds.Reverse);

                }

            }

            if (this.searchPos < 0)//如果未找到,则显示信息,将上次查找位置复原,置标志位为未找到

            {

                if (isShowFound)

                {

                    MessageBox.Show("已完成对文档的搜索,未找到搜索项", "Editor", MessageBoxButtons.OK, MessageBoxIcon.Information);

                }

                this.searchPos = this.lastSearchPos;

                isFound = false;

            }

            else

            {

                if (this.downRadioButton.Checked)

                {

                    this.searchPos += this.strSearch.Length;

                }

                else

                {

                    this.searchPos -= this.strSearch.Length;

                }

                this.parentForm.Focus();// 使主窗体获得焦点

            }

            this.lastSearchPos = this.searchPos;

            return isFound;

        }

替换功能,如果替换的字符串为空,替换和替换全部的按键不可点        

private void replaceAllButton_Click(object sender, EventArgs e)

        {

            this.strSearch = this.searchText.Text;//搜索文字

            this.strReplace = this.replaceText.Text;//替换文字

            while (SearchText(false))//直到没有匹配内容

            {

                if (this.parentForm.txtMain.SelectedText.Length > 0)//如果找到位子

                {

                    this.parentForm.txtMain.SelectedText = this.strReplace;//替换操作

                }

            }

        }

5)格式操作: 字体,颜色

这些操作大同小异,先判断选中的文本,在进行相应操作

private void 颜色ToolStripMenuItem_Click(object sender, EventArgs e)

        {

            this.colorDialog1.Color = this.txtMain.SelectionColor;

            if (this.colorDialog1.ShowDialog(this) == DialogResult.OK)

            {

                this.txtMain.SelectionColor = this.colorDialog1.Color;

            }

            this.isChanged = true;

        }

 

至于下拉菜单中改变字体的功能,先要获取系统的字体集合并加入到Items中

private void MainForm_Load(object sender, EventArgs e)

        {

            //获得系统字体列表

            InstalledFontCollection fonts = new InstalledFontCollection();

            foreach (FontFamily family in fonts.Families)

            {

                fontFamilyToolStripComboBox.Items.Add(family.Name);

            }

        }

 

 

6)工具栏中文本操作:粗体,斜体,下划线

粗体,斜体,下划线操作先要保存本来的字体属性,再在这个基础上添加相应的效果。关键代码如下:

int selectionStart = this.txtMain.SelectionStart;

                int lastEdit = selectionStart + this.txtMain.SelectionLength;

                bool flag = true;

                for (int i = selectionStart; i < lastEdit; i++)

                {

                    this.txtMain.Select(i, 1);

                    this.txtMain.SelectionFont = new System.Drawing.Font(this.txtMain.SelectionFont.FontFamily.Name, this.txtMain.SelectionFont.Size, this.txtMain.SelectionFont.Style ^ FontStyle.Bold);

                    if (!this.txtMain.SelectionFont.Bold)

                    {

                        flag = false;

                    }

                }

                this.boldButton.Checked = flag;

                this.txtMain.Select(selectionStart, lastEdit - selectionStart);

 

文本对其功能这块,注意的是根据鼠标所指文本的当前状态来确定窗口中,那三个对应的按键是否为Checked,随时替换状态;鼠标所指位置文本状态的确定,通过这个文本框事件。

private void txtMain_SelectionChanged(object sender, EventArgs e)

        {

            this.cursor();

        }

 

 

7)附加功能,编辑器背景色,字数统计

改变背景色只需要把选中的颜色改变编辑框的BackColor 即可实现

        this.txtMain.BackColor = this.colorDialog1.Color;

字数统计这个功能是仿照WPS的,不过不是很完善。

private void 字数统计ToolStripMenuItem_Click(object sender, EventArgs e)

        {

            int totalNum = 0;

            string[] strArray = this.txtMain.Text.Split(" \t\n\0".ToCharArray());

            foreach (string str in strArray)

            {

                totalNum += str.Length;

            }

            MessageBox.Show(this, string.Concat(new object[] { "当前编辑文件:\n", this.fileName, "\n字符数(计空格)            ", this.txtMain.TextLength, "\n字符数(不计空格)        ", totalNum, "\n" }), "字数统计", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

        }

 三、个人总结

     这个简易文本编辑器使用C#语言写的,在这个过程中遇到了各种问题。首先,是获取系统字体的问题。需要经过查询InstalledFontCollection 中获取系统字体,再取出系统字体的family就可以了。然后是保存时的默认格式,我想编辑为rtf(富文本)格式,可是却出现了一些我无法解决的问题,但是不影响整个程序的运行。在做查找和替换那块时,将替换全部和替换部分的事件写反了,查找了比较久才发现问题所在,命名又相近不好查错,花了好多时间。

通过本次试验,我感觉受益匪浅,也提醒了自己要心细一些。

posted on 2014-05-31 10:58  猫咪yy  阅读(355)  评论(0)    收藏  举报

导航