65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 中的智能感知文本框

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (10投票s)

2014 年 3 月 3 日

CPOL

2分钟阅读

viewsIcon

51899

downloadIcon

3323

多行文本框的自动单词补全(最小智能感知)

引言

智能感知就是指当我们输入单词的首字母时,预测单词的功能。我们都使用 Visual Studio,当我们输入类名或命名空间名时,Visual Studio 会自动显示包含该类/命名空间的成员和方法对象列表。

这个技巧肯定对你制作自己的 C# 智能感知文本框很有用。这并不是一个完美的智能感知,但它具有最小的自动单词补全能力。

系统设计

此应用程序的系统设计非常易于理解。当我们在文本框中输入文本时,弹出列表框会显示字符串中最后一个单词的首字母列表。弹出列表框中的项目是从为应用程序创建的字典列表中加载的。如果最后一个单词与列表元素不匹配,则弹出菜单会隐藏。

弹出菜单应该显示在文本行的下方,因此我们需要获取文本光标的位置。为此,我们需要调用 user32.dll 程序集中的 private extern static int GetCaretPos(out Point p) 函数。

Using the Code

AutoCompleteTextBox 是为给定的文本框创建智能感知的函数。

AutoCompleteTextBox 方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;

namespace IntellisenceTextBox
{
    class clsIntelliSense
    {
        [DllImport("user32")]
        private extern static int GetCaretPos(out Point p);

        /// <summary>
        /// <para>AutoCompleteTextBox is the method to popups when typing the keywords on TextBox to avoid the mistakes.</para>
        /// <para>Type 1:</para>
        /// <para>&#160;&#160;&#160;&#160;List&lt;string&gt; 
        ISList = new List&lt;string&gt;(new string[] { "SELECT", "CREATE", "TABLE" }); </para>
        /// <para>&#160;&#160;&#160;&#160;AutoCompleteTextBox(textBox1,listBox1, ISList,e);</para>
        /// <para></para>
        /// <para>Type 2:</para>
        /// <para>&#160;&#160;&#160;&#160;AutoCompleteTextBox(textBox1,listBox1,
        new List&lt;string&gt;(new string[] { "SELECT", "CREATE", "TABLE" }),e);</para>
        /// <para></para>
        /// <para>Type 3:</para>
        /// <para>&#160;&#160;&#160;&#160;AutoCompleteTextBox(textBox1,listBox1,
        new string[] { "SELECT", "CREATE", "TABLE" }.ToList(),e);</para>
        /// <para>Note: Don't Use Two Words in Dictionary List. Ex. "AUDI CAR" </para>
        /// </summary>
        /// <param name="txtControl">Text Box Name</param>
        /// <param name="lstControl">List Box Name</param>
        /// <param name="lstAutoCompleteList">Dictionary List</param>
        /// <param name="txtControlKEA">Text Box Key Up Event Args.</param>
        /// 
        public static void AutoCompleteTextBox(TextBox txtControl, ListBox lstControl, 
            List<string> lstAutoCompleteList, KeyEventArgs txtControlKEA)
        {
            Point cp;
            GetCaretPos(out cp);
            List<string> lstTemp = new List<string>();
            //Positioning the Listbox on TextBox by Type Insertion Cursor position
            lstControl.SetBounds(cp.X + txtControl.Left, cp.Y + txtControl.Top + 20, 150, 50);

            var TempFilteredList = lstAutoCompleteList.Where
                (n => n.StartsWith(GetLastString(txtControl.Text).ToUpper())).Select(r => r);

            lstTemp = TempFilteredList.ToList<string>();
            if (lstTemp.Count != 0 && GetLastString(txtControl.Text) != "")
            {
                lstControl.DataSource = lstTemp;
                lstControl.Show();
            }
            else
            {
                lstControl.Hide();
            }

            //Code for focusing ListBox Items While Pressing Down and UP Key. 
            if (txtControlKEA.KeyCode == Keys.Down)
            {
                lstControl.SelectedIndex = 0;
                lstControl.Focus();
                txtControlKEA.Handled = true;
            }
            else if (txtControlKEA.KeyCode == Keys.Up)
            {
                lstControl.SelectedIndex = lstControl.Items.Count - 1;
                lstControl.Focus();
                txtControlKEA.Handled = true;
            }

            //text box key press event
            txtControl.KeyPress += (s, kpeArgs) =>
            {

                if (kpeArgs.KeyChar == (char)Keys.Enter)
                {
                    if (lstControl.Visible == true)
                    {
                        lstControl.Focus();
                    }
                    kpeArgs.Handled = true;
                }
                else if (kpeArgs.KeyChar == (char)Keys.Escape)
                {
                    lstControl.Visible = false;
                    kpeArgs.Handled = true;
                }
            };

            //listbox keyup event
            lstControl.KeyUp += (s, kueArgs) =>
            {
                if (kueArgs.KeyCode == Keys.Enter)
                {
                    string StrLS = GetLastString(txtControl.Text);
                    int LIOLS = txtControl.Text.LastIndexOf(StrLS);
                    string TempStr = txtControl.Text.Remove(LIOLS);
                    txtControl.Text = TempStr + ((ListBox)s).SelectedItem.ToString();
                    txtControl.Select(txtControl.Text.Length, 0);
                    txtControl.Focus();
                    lstControl.Hide();
                }
                else if (kueArgs.KeyCode == Keys.Escape)
                {
                    lstControl.Hide();
                    txtControl.Focus();
                }
            };
        }

        private static string GetLastString(string s)
        {
            string[] strArray = s.Split(' ');
            return strArray[strArray.Length - 1];
        }
    }
}

调用该方法

文本框 KeyUp 事件适合调用上述方法。需要在文本框 KeyUp 事件中输入以下代码。

txtInput.KeyUp += (s, e) => {
                List<string> DictionaryList = new List<string>(new string[] 
                { "AZEAL", "JOB", "INFO", "SOLUTIONS", 
                "CODE", "PROJECT", "FACEBOOK", "APPLE", 
                "MICROSOFT", "WINDOWS","SELECT","SET","COM"}.ToList());
                clsIntelliSense.AutoCompleteTextBox(txtInput, lstPopup, DictionaryList, e);
            }; 

关注点

我在思考 Visual Studio 的智能感知是如何工作的时,想出了这个方法。

历史

这是一个初步的实现。稍后,我们将考虑语法和区分大小写的列表,以便在代码中实现。

错误修复:在显示列表框时,按下上下键时列表框会获得焦点。

© . All rights reserved.