在我的应用程序中,我有一个ComboBox,它包含System中安装的所有字体。我想添加功能,在用户写一封信之后,它的行为如下:
这意味着我不想使用AutoCompleteMode和AutoCompleteSource属性。
这是我处理CB的TextUpdate事件的代码:
private void tsComboBoxFontChoice_TextUpdate(object sender, EventArgs e)
{
if (!this.isBackClicked)
{
int caretPosition = this.tsComboBoxFontChoice.Text.Length;
bool isFound = false;
StringBuilder sbComboBox = new StringBuilder(this.tsComboBoxFontChoice.Text);
StringBuilder sbTextToAppend = null;
for (int i = 0; i < this.systemFonts.Families.Length;i++ )
{
StringBuilder sb = new StringBuilder(this.systemFonts.Families[i].Name);
sbTextToAppend = new StringBuilder(this.systemFonts.Families[i].Name);
int tempStopIndex= sbComboBox.Length;
if (tempStopIndex <= sb.Length)
{
sb.Remove(tempStopIndex,
this.systemFonts.Families[i].Name.Length - tempStopIndex).ToString(); //A
}
if(sbComboBox.ToString() == sb.ToString())
{
sbTextToAppend.Remove(0, tempStopIndex).ToString(); //rial
isFound = true;
break;
}
}
if (isFound)
{
sbComboBox.Append(sbTextToAppend);
this.tsComboBoxFontChoice.Text = sbComboBox.ToString();
this.tsComboBoxFontChoice.Select(caretPosition, sbComboBox.Length);
}
}
else
{
this.isBackClicked = false;
}
}
此代码完美无缺,但实际上很慢。正如您所看到的,我已经尝试使用StringBuilder,这样我就可以避免在连接时删除字符串的上下文并删除部分字符串。
您能告诉我如何改进我的代码?我需要完全不同的方法,或者我可以在这里做得更好吗?
谢谢!
答案 0 :(得分:1)
您可以在创建StringBuilder
之前比较输入的内容:
string typed = this.tsComboBoxFontChoice.Text;
for (int i = 0; i < this.systemFonts.Families.Length; i++)
{
string candidate = this.systemFonts.Families[i].Name;
if (!candidate.StartsWith(typed))
{
continue;
}
// it's a match!
...
}
通过这种方式,您最终不会为与当前值不匹配的字体计算“附加文本”。
顺便说一句,我怀疑你需要使用StringBuilder
s。
答案 1 :(得分:1)
让我们分解您的解决方案(提取方法):
// we (as a suggested font name) such a name of a system font that
// - starts with the prefix
// - if there're many such names
// (e.g. "Arial", "Arial narrow" for "Ar") take the shortest
// - when there're no fonts found just return prefix
private static String suggestedFontName(String prefix) {
String result = System.Drawing.FontFamily.Families
.Select(font => font.Name)
.Where(name => name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
.OrderBy(name => name.Length)
.ThenBy(name => name)
.FirstOrDefault();
return String.IsNullOrEmpty(result) ? prefix : result;
}
所以
private void tsComboBoxFontChoice_TextUpdate(object sender, EventArgs e) {
ComboBox box = sender as ComboBox;
// To prevent calling the event when we're adding tips for user
box.TextUpdate -= tsComboBoxFontChoice_TextUpdate;
try {
String oldText = box.Text;
String suggested = suggestedFontName(oldText);
box.Text = suggested;
box.Select(oldText.Length, suggested.Length - oldText.Length);
}
finally {
// the text is updated, so let's continue listening TextUpdate event
box.TextUpdate += tsComboBoxFontChoice_TextUpdate;
}
}