Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WiFraseC?C自动完成在文本框的中间?_C#_Winforms_Autocomplete - Fatal编程技术网

C# WiFraseC?C自动完成在文本框的中间?

C# WiFraseC?C自动完成在文本框的中间?,c#,winforms,autocomplete,C#,Winforms,Autocomplete,我有一个文本框,可以像这样自动完成: txtName.AutoCompleteMode = AutoCompleteMode.Suggest; txtName.AutoCompleteSource = AutoCompleteSource.CustomSource; txtName.AutoCompleteCustomSource = namesCollection; 它可以工作,但只在文本框的开头。我想在文本框的任何位置自动完成用户输入的任何单词。我对@PaRiMaL RaJ提出的解决方案做

我有一个文本框,可以像这样自动完成:

txtName.AutoCompleteMode = AutoCompleteMode.Suggest;
txtName.AutoCompleteSource = AutoCompleteSource.CustomSource;
txtName.AutoCompleteCustomSource = namesCollection;

它可以工作,但只在文本框的开头。我想在文本框的任何位置自动完成用户输入的任何单词。

我对@PaRiMaL RaJ提出的解决方案做了一些更改,因为当文本框位于不够高的UserControl内时,列表框没有显示出来。基本上,我没有将列表框添加到文本框的父级,而是添加到表单中,并计算表单中的绝对位置

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

namespace TubeUploader
{
    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();
            KeyDown += this_KeyDown;
            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.Tab:
                    {
                        if (_listBox.Visible)
                        {
                            InsertWord((String)_listBox.SelectedItem);
                            ResetListBox();
                            _formerValue = Text;
                        }
                        break;
                    }
                case Keys.Down:
                    {
                        if ((_listBox.Visible) && (_listBox.SelectedIndex < _listBox.Items.Count - 1))
                            _listBox.SelectedIndex++;

                        break;
                    }
                case Keys.Up:
                    {
                        if ((_listBox.Visible) && (_listBox.SelectedIndex > 0))
                            _listBox.SelectedIndex--;

                        break;
                    }
            }
        }

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

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

            if (_values != null && word.Length > 0)
            {
                String[] matches = Array.FindAll(_values,
                                                 x => (x.StartsWith(word, StringComparison.OrdinalIgnoreCase) && !SelectedValues.Contains(x)));
                if (matches.Length > 0)
                {
                    ShowListBox();
                    _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++)
                        {
                            _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 : _listBox.Width;
                        }
                    }
                }
                else
                {
                    ResetListBox();
                }
            }
            else
            {
                ResetListBox();
            }
        }

        private String GetWord()
        {
            String text = Text;
            int pos = SelectionStart;

            int posStart = text.LastIndexOf(' ', (pos < 1) ? 0 : pos - 1);
            posStart = (posStart == -1) ? 0 : posStart + 1;
            int posEnd = text.IndexOf(' ', pos);
            posEnd = (posEnd == -1) ? text.Length : posEnd;

            int length = ((posEnd - posStart) < 0) ? 0 : posEnd - posStart;

            return text.Substring(posStart, length);
        }

        private void InsertWord(String newTag)
        {
            String text = Text;
            int pos = SelectionStart;

            int posStart = text.LastIndexOf(' ', (pos < 1) ? 0 : pos - 1);
            posStart = (posStart == -1) ? 0 : posStart + 1;
            int posEnd = text.IndexOf(' ', pos);

            String firstPart = text.Substring(0, posStart) + newTag;
            String updatedText = firstPart + ((posEnd == -1) ? "" : text.Substring(posEnd, text.Length - posEnd));


            Text = updatedText;
            SelectionStart = firstPart.Length;
        }

        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);
            }
        }

    }

}
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)
            {
                Form parentForm = this.FindForm(); // new line added
                parentForm.Controls.Add(_listBox); // adds it to the form
                Point positionOnForm = parentForm.PointToClient(this.Parent.PointToScreen(this.Location)); // absolute position in the form
                _listBox.Left = positionOnForm.X;
                _listBox.Top = positionOnForm.Y + 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);
            }
        }

    }
公共类自动完成文本框:文本框
{
专用列表框(ListBox);;
增加了私人住宅;
私有字符串[]_值;
私有字符串_formerValue=String.Empty;
公共自动完成文本框()
{
初始化组件();
ResetListBox();
}
私有void InitializeComponent()
{
_listBox=新的listBox();
this.KeyDown+=this_KeyDown;
this.KeyUp+=此_KeyUp;
}
私有void ShowListBox()
{
如果(!\u已添加)
{
Form parentForm=this.FindForm();//添加了新行
parentForm.Controls.Add(_listBox);//将其添加到表单中
Point positionOnForm=parentForm.PointToClient(this.Parent.PointToScreen(this.Location));//表单中的绝对位置
_listBox.Left=positionOnForm.X;
_listBox.Top=positionOnForm.Y+高度;
_isAdded=真;
}
_Visible=true;
_listBox.BringToFront();
}
私有void ResetListBox()
{
_listBox.Visible=false;
}
private void this_KeyUp(对象发送方,KeyEventArgs e)
{
UpdateListBox();
}
private void this_KeyDown(对象发送方,KeyEventArgs e)
{
开关(如钥匙代码)
{
大小写键。输入:
案例键。选项卡:
{
如果(_listBox.Visible)
{
Text=_listBox.SelectedItem.ToString();
ResetListBox();
_formerValue=文本;
this.Select(this.Text.Length,0);
e、 已处理=正确;
}
打破
}
案例键。向下:
{
如果((_listBox.Visible)和(_listBox.SelectedIndex<_listBox.Items.Count-1))
_listBox.SelectedIndex++;
e、 已处理=正确;
打破
}
案例密钥。向上:
{
如果((_listBox.Visible)和(_listBox.SelectedIndex>0))
_listBox.SelectedIndex--;
e、 已处理=正确;
打破
}
}
}
受保护的覆盖布尔IsInputKey(Keys keyData)
{
开关(键数据)
{
案例键。选项卡:
如果(_listBox.Visible)
返回true;
其他的
返回false;
违约:
返回base.IsInputKey(keyData);
}
}
私有void UpdateListBox()
{
如果(文本==\u formerValue)
返回;
_formerValue=this.Text;
字符串字=this.Text;
如果(_值!=null&&word.Length>0)
{
string[]matches=Array.FindAll(_值,
x=>(x.ToLower().Contains(word.ToLower());
如果(匹配。长度>0)
{
ShowListBox();
_BeginUpdate();
_listBox.Items.Clear();
ForEach(匹配项,x=>_listBox.Items.Add(x));
_listBox.SelectedIndex=0;
_listBox.Height=0;
_listBox.Width=0;
焦点();
使用(Graphics Graphics=\u listBox.CreateGraphics())
{
对于(int i=0;i<\u listBox.Items.Count;i++)
{
如果(i<20)
_listBox.Height+=\u listBox.GetItemHeight(i);
//它的项目宽度大于当前项目宽度
//将其设置为新的最大项目宽度
//GetItemRectangle对我不起作用
//我们使用“\u1”添加了一点额外的空间
int itemWidth=(int)graphics.MeasureString(((字符串)_listBox.Items[i])+“_”,_listBox.Font).Width;
_listBox.Width=(_listBox.Width
其他解决方案在多行环境中对我不起作用
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)
            {
                Form parentForm = this.FindForm(); // new line added
                parentForm.Controls.Add(_listBox); // adds it to the form
                Point positionOnForm = parentForm.PointToClient(this.Parent.PointToScreen(this.Location)); // absolute position in the form
                _listBox.Left = positionOnForm.X;
                _listBox.Top = positionOnForm.Y + 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);
            }
        }

    }
using System;
using System.Drawing;
using System.Windows.Forms;

class MultiLineAutoCompleteTextBox : TextBox
{
    private ListBox _listBox;
    private bool _isAdded;
    private String[] _values;
    private String _formerValue = String.Empty;
    private int _prevBreak;
    private int _nextBreak;
    private int _wordLen;

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

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

    private void ShowListBox()
    {
        if (!_isAdded)
        {
            Form parentForm = FindForm();
            if (parentForm == null) return;

            parentForm.Controls.Add(_listBox);
            Point positionOnForm = parentForm.PointToClient(Parent.PointToScreen(Location));
            _listBox.Left = positionOnForm.X;
            _listBox.Top = positionOnForm.Y + 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:
            case Keys.Space:
            {
                if (_listBox.Visible)
                {
                    Text = Text.Remove(_prevBreak == 0 ? 0 : _prevBreak + 1, _prevBreak == 0 ? _wordLen + 1 : _wordLen);
                    Text = Text.Insert(_prevBreak == 0 ? 0 : _prevBreak + 1, _listBox.SelectedItem.ToString());
                    ResetListBox();
                    _formerValue = Text;
                    Select(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;
        if (Text.Length == 0)
        {
            _listBox.Visible = false;
            return;
        }

        _formerValue = Text;
        var separators = new[] { '|', '[', ']', '\r', '\n', ' ', '\t' };
        _prevBreak = Text.LastIndexOfAny(separators, CaretIndex > 0 ? CaretIndex - 1 : 0);
        if (_prevBreak < 1) _prevBreak = 0;
        _nextBreak = Text.IndexOfAny(separators, _prevBreak + 1);
        if (_nextBreak == -1) _nextBreak = CaretIndex;
        _wordLen = _nextBreak - _prevBreak - 1;
        if (_wordLen < 1) return;

        string word = Text.Substring(_prevBreak + 1, _wordLen);

        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 : Width; ;
                    }
                }
                _listBox.EndUpdate();
            }
            else
            {
                ResetListBox();
            }
        }
        else
        {
            ResetListBox();
        }
    }

    public int CaretIndex => SelectionStart;

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