【winform】如何实现ide的自动补全“(){}”等符号

还是继续实现ide的一些简单的功能
作为一个基本的ide怎么能没有自动补全“(){}”等符号的功能呢?
【winform】如何实现ide的自动补全“(){}”等符号_第1张图片

首先,还是先想一下这个事情。
我们希望当我们在键盘上键入“(”等符号时,软件自动帮我们补全。因为大多数语言规定,上述符号总是成对出现。所以我们希望自动补全这些符号,来提高我们的办事效率。工具的意义不就是提高我们的办事效率嘛!!!
那么思考一下这个事情具体完成的步骤,当我们输入的时候,换句话说,就是当我们在textbox中键入键值的时候,对这个键值进行判断。如果这个键值是我们希望的那几个,就在这个键值后面补上对应的键值。

如何当每次输入的时候进行判断?

在textbox中有这样几个事件,叫做keyup,keydowm,keypress。顾名思义,这几个是关于按键是事件,具体其中的详细解释,请参考如下链接:
C# 如何捕获键盘按钮和组合键以及KeyPress/KeyDown事件之间的区别 (附KeyChar/KeyCode值)
Winform下KeyDown,KeyPress,KeyUp事件的总结
因为几个事件的差异,我们选择最适合我们的,我选择的是keydowm事件。这个事件的详细解释如上连接。但是请注意,如果选择操作这个事件,那么在这个事件结束之后,鼠标的光标会移动到起点,也就是索引为0的地方,想这样:?
【winform】如何实现ide的自动补全“(){}”等符号_第2张图片
请不要问我是怎么发现的,我要静静。
【winform】如何实现ide的自动补全“(){}”等符号_第3张图片

这个问题解决之后,如何判断输入的键值呢?

我们知道,每一个事件,或者是每个控件的事件都是一个委托,里面会有一个e的对象,这个对象包含着某些值。所以我们利用,e.keychar这个属性,来进行判断。在keydowm中e.keychar这个值装的就是我们键入的值只需要判断这个的值是否与我们希望的值相等就可以啦。

解决了判断问题之后的就是我们如何操作呢?

我们需要在我们输入的键值之后插入对应的键值,这样我想到了如下代码
//拿’(‘举例

Textbox1.text=textbox1.text+’)’

这个便是我第一次想到的,本以为这样就ok了,但是我还是太天真,too young too simple。当我十分开心的打开程序进行测试的时候,惊喜的发现每次,无论你的(在什么地方键入,那个“)”总是如幽灵般的出现在最后。惊喜不惊喜,意外不意外。
【winform】如何实现ide的自动补全“(){}”等符号_第4张图片
【winform】如何实现ide的自动补全“(){}”等符号_第5张图片
当我花费了很长时间,很多精力慢慢断电调试之后,发现了问题,就是赋值的那行代码,是在文本最后加上),emmmmm。
这个是一眼就可以看出来的地方。但是当你按照自己的思路把东西写出来的时候,其实你是很难发现其中的问题的,因为你写的东西就是基于你自己的理解。所以当你一顿操作猛如虎,然后定睛一看原地杵。你写的东西不会按照你的理解运行下去,总是想给你来点惊喜。所以自我感觉很阔怕。
【winform】如何实现ide的自动补全“(){}”等符号_第6张图片
然后接着说我是怎么解决的,在我的上一篇博客上面写道,我们可以根据rank()函数,得到每次的行和列的坐标。然后根据这个坐标我们可以算出来,每个光标所在的索引,根据这个索引在对字符串进行插入,这就是基本操作了。
差不多思路就这些咯,下面是实现的具体代码,可能不过简洁完美,但是也是个思路,希望给大家一点启发。
Ps:其实最开始出现的问体就是上文说的光标索引为0的问题,问题截图也放在了上面。这个问题的解决方案就是重新定位焦点。方法也如下。坐标问题请参考我的上一篇博客。
话不多说,下面放代码。

		//将左右一样的符号拿出来,单练
        char[] eschar = { '"', '\'' };
        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            //char key = e.KeyChar;
            //MessageBox.Show(key.ToString());
            //for语句用来循环判断数组里有没有我们希望的值
            for (
                int i = 0; i < 2; i++)
            {
                if (e.KeyChar == eschar[i])
                {

					//调用方法得到数据
                    LineColumn lc = Ranks();
                    //得到所在行第一个字符的索引
                    int index = textBox1.GetFirstCharIndexOfCurrentLine();
                    //这个加不加都行
                    int number = index + lc.column;
                    //根据索引插入字符串
                    textBox1.Text = textBox1.Text.Insert(number, eschar[i].ToString());
                    //定位焦点
                    textBox1.Select(number, 0);

                }
            }
            //if语句用来判断
             if (e.KeyChar == '(')
            {
                LineColumn lc = Ranks();
                int index = textBox1.GetFirstCharIndexOfCurrentLine();
                int number = index + lc.column;
                textBox1.Text= textBox1.Text.Insert(number,")");
                textBox1.Select(number, 0);
            }
            else if (e.KeyChar == '{')
            {
                LineColumn lc = Ranks();
                int index = textBox1.GetFirstCharIndexOfCurrentLine();
                int number = index + lc.column;
                textBox1.Text = textBox1.Text.Insert(number, "}");
                textBox1.Select(number, 0);
            }
            else if (e.KeyChar == '<')
            {
                LineColumn lc = Ranks();
                int index = textBox1.GetFirstCharIndexOfCurrentLine();
                int number = index + lc.column;
                textBox1.Text = textBox1.Text.Insert(number, ">");
                textBox1.Select(number, 0);
            }
            else if (e.KeyChar == '[')
            {
                LineColumn lc = Ranks();
                int index = textBox1.GetFirstCharIndexOfCurrentLine();
                int number = index + lc.column;
                textBox1.Text = textBox1.Text.Insert(number, "]");
                textBox1.Select(number, 0);
            }
        }

ps:我不习惯写一堆方法,然后告诉这玩意有啥子用,这些我们都可以百度出来。我先把我对这个事情的理解写下来,然后根据这个理解我们去找相应的方法。
小白一个,希望各路大佬多多指正。

你可能感兴趣的:(winform)