忽略重音的文本框上的自动完成
Posted
技术标签:
【中文标题】忽略重音的文本框上的自动完成【英文标题】:AutoComplete on a TextBox ignoring accentuation 【发布时间】:2021-06-20 02:43:59 【问题描述】:我有一个自定义的 TextBox
控件(它是一个自定义控件,而不是常规控件,可以在其上显示提示文本),其中我有一个 AutoComplete
从我的数据库中获取数据像这样使用DataSet
string[] postSource = aux.Tables[0].AsEnumerable().Select<System.Data.DataRow, String>(x => x.Field<String>("nm_industria")).ToArray();
var source = new AutoCompleteStringCollection();
source.AddRange(postSource);
txb_regClientData.AutoCompleteCustomSource = source;
txb_regClientData.AutoCompleteMode = AutoCompleteMode.Suggest;
txb_regClientData.AutoCompleteSource = AutoCompleteSource.CustomSource;
它给了我这个结果
Image 如果我输入“João”,它会给我正确的结果,但如果我输入“Joao”,它不会出现,从一些关于此事的阅读中我知道 AutoComplete
中没有任何内容可以自动忽略重音,所以我需要自己编写代码。我的问题是,我从哪里开始?我理想的解决方案是覆盖我的自定义控件的AutoComplete
代码中的某些内容,我阅读了 TextBox 的文档但找不到任何内容,所以如果有人能告诉我正确的方向,以便我可以阅读和学习如何做到这一点,将不胜感激。
【问题讨论】:
看来this answer 对你来说是一个好的开始。至于其余的,我可能会建议编写一个包含字符串表示形式的包装类,甚至是字典。并在 textchanged 事件中进行过滤? 这是一个很好的线索,也通过制作包装器和过滤 textchanged,您的意思是自己制作整个 AutoComplete,或者类似于更改 AutoComplete 获取的输入的东西? " 或类似于更改自动完成输入的内容"实际上这是我的第一个想法。给出一种表示用于过滤和一种表示用于显示。但后来我认为,这可能是不可能的,你必须经历“自己制作整个自动完成”的麻烦 设法获得一个更改为最佳建议的标签,整个代码都在我的自定义控件中,我想我会看看我是否可以将listbox
附加到textbox
与建议
【参考方案1】:
仍有待改进,但此代码实现了解决方案,它将listBox
“附加”到textBox
,由于命名而存在多个这些问题时会出现问题,但这应该是对于寻找类似东西的人来说,这是一个很好的起点/参考。
public class ExTextBox : TextBox
private bool alreadyRun = false;
ListBox suggestions = new ListBox();
int maxSize = 10;
string[] source;
public string Hint
public int MaxSuggestionBoxSize
get return maxSize;
set maxSize = value; this.Invalidate();
protected override void OnCreateControl()
if (alreadyRun == false) // This is only supposed to be run once, but in some situations depending on the design of the main form,
// this might need to be somewhere that gets called multiple times, this variable makes so this code is only run once even in those situations
suggestions.Name = "suggList_" + this.Name;
suggestions.Location = new Point(this.Location.X, (this.Location.Y + this.Size.Height));
suggestions.Size = new Size(this.Size.Width, this.Size.Height);
this.Parent.Controls.Add(suggestions);
this.Parent.Controls["suggList_" + this.Name].MouseDoubleClick += suggList_MouseDoubleClick;
this.Parent.Controls["suggList_" + this.Name].Hide();
alreadyRun = true;
base.OnCreateControl();
private void suggList_MouseDoubleClick(object sender, System.EventArgs e)
this.Text = this.Parent.Controls["suggList_" + this.Name].Text;
protected override void OnLeave(EventArgs e)
base.OnLeave(e);
if(source != null) // Makes sure this code is only executed when the suggestion box is being used, by checking the existance of the source
try
if (this.Parent.Controls["suggList_" + this.Name].Focused == false)
this.Parent.Controls["suggList_" + this.Name].Hide();
catch
protected override void OnTextChanged(EventArgs e)
base.OnTextChanged(e);
AutoCompleteSmart();
public void AutoCompleteSmart()
if (source != null)
suggestions.Items.Clear();
if (this.Text != "")
foreach (string a in source)
if (RemoveDiacritics(a.ToLower()).Contains(RemoveDiacritics(this.Text.ToLower())))
suggestions.Items.Add(a);
this.Parent.Controls.Remove(suggestions);
if (suggestions.Items.Count < maxSize) // Optional code, defines a limit size for the suggestion box
suggestions.Size = new Size(this.Size.Width, ((suggestions.ItemHeight * suggestions.Items.Count) + suggestions.ItemHeight));
else
suggestions.Size = new Size(this.Size.Width, ((suggestions.ItemHeight * maxSize) + suggestions.ItemHeight));
this.Parent.Controls.Add(suggestions);
this.Parent.Controls["suggList_" + this.Name].BringToFront();
this.Parent.Controls["suggList_" + this.Name].Show();
else
this.Parent.Controls["suggList_" + this.Name].Hide();
public void AutoCompleteSmartSource(string[] _source)
source = _source;
private static string RemoveDiacritics(string text)
var normalizedString = text.Normalize(NormalizationForm.FormD);
var stringBuilder = new StringBuilder();
foreach (var c in normalizedString)
var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
if (unicodeCategory != UnicodeCategory.NonSpacingMark)
stringBuilder.Append(c);
return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
【讨论】:
以上是关于忽略重音的文本框上的自动完成的主要内容,如果未能解决你的问题,请参考以下文章