Auto-HTML tags completion in C#

Viewed 132

i've been trying to implement a Auto-HTML tags feature in a Winforms Richtextbox. I'm a beginner in C# and i needed a reference so i've come across this article on CodeProject. With this given code:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;

    namespace AutoCompleteHTMLTags_CSharp
    {
        public partial class Simple_Form : Form
        {
            public Simple_Form()
            {
                InitializeComponent();
            }

            public static String EnteredString = "";
            public static Boolean Is_LessThanKeyPressed = false;
            public static Boolean Is_GreaterThanKeyPressed = false;
            public static Boolean Is_AutoCompleteCharacterPressed = false;
            public Boolean Is_SpaceBarKeyPressed = false;
            public Boolean Is_TagClosedKeyPressed = false;

            public String[] tagslist ={
            "html",
            "head",
            "title",
            "body",
            "h1",
            "h2",
            "h3",
            "h4",
            "h5",
            "h6",
            "b",
            "u",
            "i",
            "sub",
            "sup",
            "center",
            "strike",
            "font",
            "p",
            "style",
            "pre",
            "marquee",
            "ul",
            "ol",
            "a",
            "img",
            "table",
            "tr",
            "th",
            "td",
            "frameset",
            "iframe",
            "form",
            "input",
            "button",
            "textarea",
            "select",
            "div",
            "fieldset",
            "span",
            "strong",
            "em",
            "big",
            "small"
            };


            public void ProcessAutoCompleteBrackets(String s)
            {
                int sel = richTextBox1.SelectionStart;
                switch (s)
                {
                    case "(":
                        richTextBox1.Text = richTextBox1.Text.Insert(sel, ")");
                        richTextBox1.SelectionStart = sel;
                        Is_AutoCompleteCharacterPressed = true;
                        break;

                    case "[":
                        richTextBox1.Text = richTextBox1.Text.Insert(sel, "]");
                        richTextBox1.SelectionStart = sel;
                        Is_AutoCompleteCharacterPressed = true;
                        break;

                    case "\"":
                        Is_AutoCompleteCharacterPressed = true;
                        richTextBox1.Text = richTextBox1.Text.Insert(sel, "\"");
                        richTextBox1.SelectionStart = sel;
                        break;

                    case "'":
                        richTextBox1.Text = richTextBox1.Text.Insert(sel, "'");
                        richTextBox1.SelectionStart = sel;
                        Is_AutoCompleteCharacterPressed = true;
                        break;
                }
            }



            private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
            {
                String ch = e.KeyChar.ToString();


                this.ProcessAutoCompleteBrackets(ch);

                if (ch == "<")
                {
                    Is_LessThanKeyPressed = true;
                    Is_SpaceBarKeyPressed = false;
                    EnteredString = "";
                }
                else if (ch == ">")
                {
                    if (!Is_TagClosedKeyPressed)
                    {
                        Is_GreaterThanKeyPressed = true;
                        Is_SpaceBarKeyPressed = false;

                        int oldsel = richTextBox1.SelectionStart;

                        for (int i = 0; i < tagslist.Length; i++)
                        {
                            if (EnteredString == tagslist[i])
                            {
                                richTextBox1.Text = richTextBox1.Text.Insert(oldsel, "</" + tagslist[i] + ">");
                                richTextBox1.SelectionStart = richTextBox1.SelectionStart + oldsel;
                                EnteredString = "";
                            }
                        }

                        Is_LessThanKeyPressed = false;
                    }
                    else
                    {
                        Is_TagClosedKeyPressed = false;
                    }
                }

                else
                {
                    if (Is_LessThanKeyPressed)
                    {
                        for (char a = 'a'; a <= 'z'; a++)
                        {
                            if (a.ToString() == ch)
                            {
                                EnteredString += ch;
                            }
                            else if (a.ToString().ToUpper() == ch)
                            {
                                EnteredString += ch;
                            }
                        }
                        for (int a = 0; a <= 9; a++)
                        {
                            if (a.ToString() == ch)
                            {
                                EnteredString += ch;
                            }
                        }
                    }
                }


                // if user itself closes the tag
                if (Is_LessThanKeyPressed)
                {
                    if (ch == "/")
                    {
                        Is_TagClosedKeyPressed = true;
                        Is_SpaceBarKeyPressed = true;
                        EnteredString = "";
                    }
                }
            }

            private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
            {
                switch (e.KeyCode)
                {
                    case Keys.Space:
                        Is_SpaceBarKeyPressed = true;

                        if (Is_GreaterThanKeyPressed)
                        {
                            Is_GreaterThanKeyPressed = false;
                        }
                        Is_LessThanKeyPressed = false;

                        for (int i = 0; i < tagslist.Length; i++)
                        {
                            if(EnteredString==tagslist[i])
                            {
                                EnteredString = tagslist[i];
                            }
                        }
                        break;

                    case Keys.Up:
                        if (Is_AutoCompleteCharacterPressed == false)
                        {
                            EnteredString = "";
                            Is_AutoCompleteCharacterPressed = false;
                        }
                        Is_SpaceBarKeyPressed = false;
                        break;

                    case Keys.Down:
                        if (Is_AutoCompleteCharacterPressed == false)
                        {
                            EnteredString = "";
                            Is_AutoCompleteCharacterPressed = false;
                        }
                        Is_SpaceBarKeyPressed = false;
                        break;

                    case Keys.Left:
                        if (Is_AutoCompleteCharacterPressed == false)
                        {
                            EnteredString = "";
                            Is_AutoCompleteCharacterPressed = false;
                        }
                        Is_SpaceBarKeyPressed = false;
                        break;

                    case Keys.Right:
                        if (Is_AutoCompleteCharacterPressed == false)
                        {
                            EnteredString = "";
                            Is_AutoCompleteCharacterPressed = false;
                        }
                        Is_SpaceBarKeyPressed = false;
                        break;

                    case Keys.Enter: EnteredString = "";
                        Is_SpaceBarKeyPressed = false;
                        break;

                    case Keys.Back:
                        int sel = richTextBox1.SelectionStart;
                        Point pt = richTextBox1.GetPositionFromCharIndex(sel);
                        char ch = richTextBox1.GetCharFromPosition(pt);
                        if (EnteredString.Length > 0)
                        {
                            if (ch != '>')
                            {
                                EnteredString = EnteredString.Remove(EnteredString.Length - 1);
                                Is_LessThanKeyPressed = true;
                            }
                        }
                        if (ch == '<')
                        {
                            EnteredString = "";
                        }
                        break;
                }
            }
        }
    }

Problem:

The implementation works fine, the only problem is when you type <html> (or any other keyword), the completion becomes </html>, but it scrolls down to the end of the TextBox:

Demo of Auto tags

Anyone knows how to fix this?

2 Answers

In the ScrollToCaret() method, the RichTextBox will scroll the contents of the control to the current caret position.

If you want to muck around with low level messages like the scrolling position, you'll have to drop to the Win32 message level, the RTB doesn't give you any kind of fine grain control over it out of the box.

Specifically you want to look at EM_GETSCROLLPOS and EM_SETSCROLLPOS, which return and set a POINT structure respectively of the character to display in the top-left corner (ie, the scroll position). You store the current scroll position, edit the string and set the scroll position back to what you stored previously.

Related