的WinForms | C#|自动完成在一个文本框的中间? [英] WinForms | C# | AutoComplete in the Middle of a Textbox?
本文介绍了的WinForms | C#|自动完成在一个文本框的中间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个文本框,做自动完成,像这样:
txtName.AutoCompleteMode = AutoCompleteMode.Suggest;
txtName.AutoCompleteSource = AutoCompleteSource.CustomSource;
txtName.AutoCompleteCustomSource = namesCollection;
它的工作原理,但仅在文本框的开头。我想自动完成踢在用户输入任何文字,在文本框中的任何位置。
解决方案
使用系统;
使用System.Collections.Generic;
使用System.Drawing中;
使用System.Windows.Forms的;命名空间TubeUploader
{
公共类AutoCompleteTextBox:文本框
{
私人列表框_listBox;
私人布尔_isAdded;
私有String [] _values;
私人字符串_formerValue =的String.Empty; 公共AutoCompleteTextBox()
{
的InitializeComponent();
ResetListBox();
} 私人无效的InitializeComponent()
{
_listBox =新的ListBox();
的KeyDown + = this_KeyDown;
的KeyUp + = this_KeyUp;
} 私人无效ShowListBox()
{
如果(!_isAdded)
{
Parent.Controls.Add(_listBox);
_listBox.Left =左;
_listBox.Top =上衣+高度;
_isAdded = TRUE;
}
_listBox.Visible = TRUE;
_listBox.BringToFront();
} 私人无效ResetListBox()
{
_listBox.Visible = FALSE;
} 私人无效this_KeyUp(对象发件人,发送KeyEventArgs E)
{
UpdateListBox();
} 私人无效this_KeyDown(对象发件人,发送KeyEventArgs E)
{
开关(e.Key code)
{
案例Keys.Tab:
{
如果(_listBox.Visible)
{
InsertWord((字符串)_listBox.SelectedItem);
ResetListBox();
_formerValue =文本;
}
打破;
}
案例Keys.Down:
{
如果((_listBox.Visible)及及(_listBox.SelectedIndex&下; _listBox.Items.Count - 1))
_listBox.SelectedIndex ++; 打破;
}
案例Keys.Up:
{
如果((_listBox.Visible)及及(_listBox.SelectedIndex大于0))
_listBox.SelectedIndex--; 打破;
}
}
} 保护覆盖布尔IsInputKey(钥匙KEYDATA)
{
开关(KEYDATA)
{
案例Keys.Tab:
返回true;
默认:
返回base.IsInputKey(KEYDATA);
}
} 私人无效UpdateListBox()
{
如果(文字== _formerValue)回报;
_formerValue =文本;
串词=朗朗上口(); 如果(_values =空&放大器;!&放大器; word.Length大于0)
{
的String [] =匹配Array.FindAll(_values,
X => (x.StartsWith(文字,StringComparison.OrdinalIgnoreCase)及和放大器;!SelectedValues.Contains(X)));
如果(matches.Length大于0)
{
ShowListBox();
_listBox.Items.Clear();
Array.ForEach(比赛中,x => _listBox.Items.Add(X));
_listBox.SelectedIndex = 0;
_listBox.Height = 0;
_listBox.Width = 0;
焦点();
使用(图形图像= _listBox.CreateGraphics())
{
的for(int i = 0; I< _listBox.Items.Count;我++)
{
_listBox.Height + = _listBox.GetItemHeight(ⅰ);
//它项宽度是比当前的大
//将其设置为新的最大宽度项
// GetItemRectangle不为我工作
//我们通过添加一些额外的空间,_
INT itemWidth =(int)的graphics.MeasureString(((字符串)_listBox.Items [I])+__listBox.Font).WIDTH;
_listBox.Width =(_listBox.Width< itemWidth)? itemWidth:_listBox.Width;
}
}
}
其他
{
ResetListBox();
}
}
其他
{
ResetListBox();
}
} 私人字符串朗朗上口()
{
字符串文本=文本;
INT POS = SelectionStart; INT posStart = text.LastIndexOf('',(正 - 。1)?0:POS - 1);
posStart =(posStart == -1)? 0:posStart + 1;
INT posEnd = text.IndexOf('',POS机);
posEnd =(posEnd == -1)? text.Length:posEnd; INT长度=((posEnd - posStart)小于0)? 0:posEnd - posStart; 返回text.Substring(posStart,长度);
} 私人无效InsertWord(字符串newTag)
{
字符串文本=文本;
INT POS = SelectionStart; INT posStart = text.LastIndexOf('',(正 - 。1)?0:POS - 1);
posStart =(posStart == -1)? 0:posStart + 1;
INT posEnd = text.IndexOf('',POS机); 串firstPart = text.Substring(0,posStart)+ newTag;
字符串updatedText = firstPart +(?(posEnd == -1):text.Substring(posEnd,text.Length - posEnd));
文本= updatedText;
SelectionStart = firstPart.Length;
} 公众的String []值
{
得到
{
返回_values;
}
组
{
_values =价值;
}
} 公开名单<串GT; SelectedValues
{
得到
{
的String []结果= Text.Split(新[] {''},StringSplitOptions.RemoveEmptyEntries);
返回新的List<串GT;(结果);
}
} }}
用法示例
使用系统;
使用System.Windows.Forms的;命名空间自动完成
{
公共部分类TESTFORM:表单
{
私人只读的String [] = _values {一,二,三化,树,四有,fivee}; 公共TESTFORM()
{
的InitializeComponent();
//自动完成是我们在表格上的特殊文本框控件
AutoComplete.Values = _values;
} }
}
I have a textbox that does autocompletion like so:
txtName.AutoCompleteMode = AutoCompleteMode.Suggest;
txtName.AutoCompleteSource = AutoCompleteSource.CustomSource;
txtName.AutoCompleteCustomSource = namesCollection;
It works, but only at the beginning of a textbox. I'd like autocomplete to kick in for any word the user is entering, at any position in the textbox.
解决方案
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);
}
}
}
}
Sample Usage
using System;
using System.Windows.Forms;
namespace AutoComplete
{
public partial class TestForm : Form
{
private readonly String[] _values = { "one", "two", "three", "tree", "four", "fivee" };
public TestForm()
{
InitializeComponent();
// AutoComplete is our special textbox control on the form
AutoComplete.Values = _values;
}
}
}
这篇关于的WinForms | C#|自动完成在一个文本框的中间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文