我正在寻找一个 WinForm 控件,它可以为多个空格分隔提供自动完成行为 - 正是 ala del.icio.us(或 stackoverflow.com)。
有谁知道如何在 .NET 2.0 WinForm 应用程序中做到这一点?
我正在寻找一个 WinForm 控件,它可以为多个空格分隔提供自动完成行为 - 正是 ala del.icio.us(或 stackoverflow.com)。
有谁知道如何在 .NET 2.0 WinForm 应用程序中做到这一点?
ComboBox 可以自动完成,但一次只能完成一个单词。
如果你想让每个单词分别自动完成,你必须自己写。
我已经做了,希望不会太长。它不是 100% 完全符合您的要求,它用于在输入电子邮件地址时在电子邮件客户端中自动完成。
/// <summary>
/// Extended TextBox with smart auto-completion
/// </summary>
public class TextBoxAC: TextBox
{
private List<string> completions = new List<string>();
private List<string> completionsLow = new List<string>();
private bool autocompleting = false;
private bool acDisabled = true;
private List<string> possibleCompletions = new List<string>();
private int currentCompletion = 0;
/// <summary>
/// Default constructor
/// </summary>
public TextBoxAC()
{
this.TextChanged += new EventHandler(TextBoxAC_TextChanged);
this.KeyPress += new KeyPressEventHandler(TextBoxAC_KeyPress);
this.KeyDown += new KeyEventHandler(TextBoxAC_KeyDown);
this.TabStop = true;
}
/// <summary>
/// Sets autocompletion data, list of possible strings
/// </summary>
/// <param name="words">Completion words</param>
/// <param name="wordsLow">Completion words in lowerCase</param>
public void SetAutoCompletion(List<string> words, List<string> wordsLow)
{
if (words == null || words.Count < 1) { return; }
this.completions = words;
this.completionsLow = wordsLow;
this.TabStop = false;
}
private void TextBoxAC_TextChanged(object sender, EventArgs e)
{
if (this.autocompleting || this.acDisabled) { return; }
string text = this.Text;
if (text.Length != this.SelectionStart) { return; }
int pos = this.SelectionStart;
string userPrefix = text.Substring(0, pos);
int commaPos = userPrefix.LastIndexOf(",");
if (commaPos == -1)
{
userPrefix = userPrefix.ToLower();
this.possibleCompletions.Clear();
int n = 0;
foreach (string s in this.completionsLow)
{
if (s.StartsWith(userPrefix))
{
this.possibleCompletions.Add(this.completions[n]);
}
n++;
}
if (this.possibleCompletions.Count < 1) { return; }
this.autocompleting = true;
this.Text = this.possibleCompletions[0];
this.autocompleting = false;
this.SelectionStart = pos;
this.SelectionLength = this.Text.Length - pos;
}
else
{
string curUs = userPrefix.Substring(commaPos + 1);
if (curUs.Trim().Length < 1) { return; }
string trimmed;
curUs = this.trimOut(curUs, out trimmed);
curUs = curUs.ToLower();
string oldUs = userPrefix.Substring(0, commaPos + 1);
this.possibleCompletions.Clear();
int n = 0;
foreach (string s in this.completionsLow)
{
if (s.StartsWith(curUs))
{
this.possibleCompletions.Add(this.completions[n]);
}
n++;
}
if (this.possibleCompletions.Count < 1) { return; }
this.autocompleting = true;
this.Text = oldUs + trimmed + this.possibleCompletions[0];
this.autocompleting = false;
this.SelectionStart = pos;
this.SelectionLength = this.Text.Length - pos + trimmed.Length;
}
this.currentCompletion = 0;
}
private void TextBoxAC_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete)
{
this.acDisabled = true;
}
if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down)
{
if ((this.acDisabled) || (this.possibleCompletions.Count < 1))
{
return;
}
e.Handled = true;
if (this.possibleCompletions.Count < 2) { return; }
switch (e.KeyCode)
{
case Keys.Up:
this.currentCompletion--;
if (this.currentCompletion < 0)
{
this.currentCompletion = this.possibleCompletions.Count - 1;
}
break;
case Keys.Down:
this.currentCompletion++;
if (this.currentCompletion >= this.possibleCompletions.Count)
{
this.currentCompletion = 0;
}
break;
}
int pos = this.SelectionStart;
string userPrefix = this.Text.Substring(0, pos);
int commaPos = userPrefix.LastIndexOf(",");
if (commaPos == -1)
{
pos--;
userPrefix = this.Text.Substring(0, pos);
this.autocompleting = true;
this.Text = userPrefix + this.possibleCompletions[this.currentCompletion].Substring(userPrefix.Length);
this.autocompleting = false;
this.SelectionStart = pos + 1;
this.SelectionLength = this.Text.Length - pos;
}
else
{
string curUs = userPrefix.Substring(commaPos + 1);
if (curUs.Trim().Length < 1) { return; }
string trimmed;
curUs = this.trimOut(curUs, out trimmed);
curUs = curUs.ToLower();
string oldUs = userPrefix.Substring(0, commaPos + 1);
this.autocompleting = true;
this.Text = oldUs + trimmed + this.possibleCompletions[this.currentCompletion];
this.autocompleting = false;
this.SelectionStart = pos;
this.SelectionLength = this.Text.Length - pos + trimmed.Length;
}
}
}
private void TextBoxAC_KeyPress(object sender, KeyPressEventArgs e)
{
if (!Char.IsControl(e.KeyChar)) { this.acDisabled = false; }
}
private string trimOut(string toTrim, out string trim)
{
string ret = toTrim.TrimStart();
int pos = toTrim.IndexOf(ret);
trim = toTrim.Substring(0, pos);
return ret;
}
}