自动完成,看起来对符号的字符串包含,而不是打头 [英] Autocomplete that looks for symbols a string contains rather than starts with

查看:103
本文介绍了自动完成,看起来对符号的字符串包含,而不是打头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写在一个点上实现了一个文本框与自动完成程序。目前,为了简化目的,我使用 CustomSource 手动填充通过在设计时的几个条目。虽然自动完成正常工作,我想它提出建议,不单纯的开始的当前输入的文字,但包含它的在存储选择的任何位置。

I'm writing a program that at one point implements a TextBox with autocomplete. Currently, for purpose of simplicity I'm using CustomSource manually populated by several entries at design time. While autocomplete works fine, I'd like it to make suggestions that don't simply start with the currently entered text, but contain it at any position in the stored choices.

例如,如果词地球,叶,和滑翔的存储选项,键入GL正确地提出两个地球和滑翔。

For example, if words "globe", "lobe", and "glide" are the stored options, typing in "gl" correctly suggests both "globe" and "glide".

不过,我想它表明这两个地球和叶时,吊球中键入。我不完全知道如何处理这一点。

However, I'd like it to suggest both "globe" and "lobe" when "lob" is typed in. I'm not exactly sure how to approach this.

有没有人这样做过? VB.NET或C#都好,只要我能找出一个适当的.NET的方式来做到这一点。

Has anyone done this before? VB.NET or C# are both fine, as long as I can figure out a proper .NET way to do this.

干杯! =)

推荐答案

所以,我一直在寻找这样的事情。与自动完成了一个文本框包含搜索,而不是StartsWith。

So i was looking for something like this. A TextBox with AutoComplete with a Contains search instead of a StartsWith.

这个翻译是从这个<一个href="http://stackoverflow.com/questions/1437002/winforms-c-sharp-autocomplete-in-the-middle-of-a-textbox">WinForms | C#|自动完成的文本框的中间?

我能做出这一点,这里是我的版本,它使用包含一个自动完成的。我希望每个人都认为这可用。

I was able to make this, here is my version of an autocomplete that uses Contains. I hope everyone finds this usable.

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

namespace TowInvoicing
{
    //from http://stackoverflow.com/questions/1437002/winforms-c-sharp-autocomplete-in-the-middle-of-a-textbox
    public class AutoCompleteTextBox : TextBox
    {
        private ListBox _listBox;
        private bool _isAdded;
        private String[] _values;
        private String _formerValue = String.Empty;

        public AutoCompleteTextBox()
        {
            InitializeComponent();
            ResetListBox();
        }

        private void InitializeComponent()
        {
            _listBox = new ListBox();
            this.KeyDown += this_KeyDown;
            this.KeyUp += this_KeyUp;
        }

        private void ShowListBox()
        {
            if (!_isAdded)
            {
                Parent.Controls.Add(_listBox);
                _listBox.Left = Left;
                _listBox.Top = Top + Height;
                _isAdded = true;
            }
            _listBox.Visible = true;
            _listBox.BringToFront();
        }

        private void ResetListBox()
        {
            _listBox.Visible = false;
        }

        private void this_KeyUp(object sender, KeyEventArgs e)
        {
            UpdateListBox();
        }

        private void this_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Enter:
                case Keys.Tab:
                    {
                        if (_listBox.Visible)
                        {
                            Text = _listBox.SelectedItem.ToString();
                            ResetListBox();
                            _formerValue = Text;
                            this.Select(this.Text.Length, 0);
                            e.Handled = true;
                        }
                        break;
                    }
                case Keys.Down:
                    {
                        if ((_listBox.Visible) && (_listBox.SelectedIndex < _listBox.Items.Count - 1))
                            _listBox.SelectedIndex++;
                        e.Handled = true;
                        break;
                    }
                case Keys.Up:
                    {
                        if ((_listBox.Visible) && (_listBox.SelectedIndex > 0))
                            _listBox.SelectedIndex--;
                        e.Handled = true;
                        break;
                    }


            }
        }

        protected override bool IsInputKey(Keys keyData)
        {
            switch (keyData)
            {
                case Keys.Tab:
                    if (_listBox.Visible)
                        return true;
                    else
                        return false;
                default:
                    return base.IsInputKey(keyData);
            }
        }

        private void UpdateListBox()
        {
            if (Text == _formerValue)
                return;

            _formerValue = this.Text;
            string word = this.Text;

            if (_values != null && word.Length > 0)
            {
                string[] matches = Array.FindAll(_values,
                                                 x => (x.ToLower().Contains(word.ToLower())));
                if (matches.Length > 0)
                {
                    ShowListBox();
                    _listBox.BeginUpdate();
                    _listBox.Items.Clear();
                    Array.ForEach(matches, x => _listBox.Items.Add(x));
                    _listBox.SelectedIndex = 0;
                    _listBox.Height = 0;
                    _listBox.Width = 0;
                    Focus();
                    using (Graphics graphics = _listBox.CreateGraphics())
                    {
                        for (int i = 0; i < _listBox.Items.Count; i++)
                        {
                            if (i < 20)
                                _listBox.Height += _listBox.GetItemHeight(i);
                            // it item width is larger than the current one
                            // set it to the new max item width
                            // GetItemRectangle does not work for me
                            // we add a little extra space by using '_'
                            int itemWidth = (int)graphics.MeasureString(((string)_listBox.Items[i]) + "_", _listBox.Font).Width;
                            _listBox.Width = (_listBox.Width < itemWidth) ? itemWidth : this.Width;;
                        }
                    }
                    _listBox.EndUpdate();
                }
                else
                {
                    ResetListBox();
                }
            }
            else
            {
                ResetListBox();
            }
        }

        public String[] Values
        {
            get
            {
                return _values;
            }
            set
            {
                _values = value;
            }
        }

        public List<String> SelectedValues
        {
            get
            {
                String[] result = Text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                return new List<String>(result);
            }
        }

    }

}

这篇关于自动完成,看起来对符号的字符串包含,而不是打头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆