自动完成查找字符串包含的符号而不是开头的符号 [英] Autocomplete that looks for symbols a string contains rather than starts with

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

问题描述

我正在编写一个程序,该程序在某一时刻实现了具有自动完成功能的 TextBox.目前,为了简单起见,我在设计时使用由多个条目手动填充的 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.

例如,如果单词globe"、lobe"和glide"是存储的选项,则输入gl"正确提示globe"和glide".

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

但是,当输入lob"时,我希望它同时建议globe"和lobe".我不确定如何处理这个问题.

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.

此版本来自 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 https://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天全站免登陆