ComboBox,提示文字

时间:2015-09-17 11:49:53

标签: c# winforms combobox

在我的应用程序中,我有一个ComboBox,它包含System中安装的所有字体。我想添加功能,在用户写一封信之后,它的行为如下:

enter image description here

这意味着我不想使用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,这样我就可以避免在连接时删除字符串的上下文并删除部分字符串。

您能告诉我如何改进我的代码?我需要完全不同的方法,或者我可以在这里做得更好吗?

谢谢!

2 个答案:

答案 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;
  }
}