1

我想实现一个工具条组合框,它的作用类似于设置为建议的自动完成模式。我没有设置自动完成模式,因为它只找到前缀相同的项目。

我想要的是它也可以在组合框中找到具有子字符串的项目,即使它不以 that 开头

样品清单:

一月、二月、三月、四月、五月、六月、七月、八月、九月、十月、十一月、十二月

如果我在工具条组合框中输入"ber",它应该显示在下拉列表中:

九月
十月
十一月
十二月

分别。

截至目前,我创建了一个单独的列表,其中包含以下项目:

void populateList()
{
  this->storageList = gcnew Generic::List<String ^>;
  storageList->Add("January");
  storageList->Add("February");
  storageList->Add("March");
  storageList->Add("April");
  storageList->Add("May");
  storageList->Add("June");
  storageList->Add("July");
  storageList->Add("August");
  storageList->Add("September");
  storageList->Add("October");
  storageList->Add("November");
  storageList->Add("December");
}

我为 ToolStripCombobox 添加了一个 TextUpdate 事件:

      void handleTextChange()
      {
        String ^ searchText = toolStripComboBox->Text;
        toolStripComboBox->Items->Clear();
        Cursor->Current = Cursors::Default;

        if(searchText != "")
        {
          toolStripComboBox->DroppedDown = true;
          Regex ^ searchRegex = gcnew Regex("(?i).*"+searchText+".*");
          for(int i = 0; i<storageList->Count; i++)
          {
            Match ^ m = searchRegex->Match(storageList[i]);
            if(m->Success)
            {
              toolStripComboBox->Items->Add(storageList[i]);
            }
          }

          if(toolStripComboBox->Items->Count > 0)
          {
            String ^ sText = toolStripComboBox->Items[0]->ToString();
            toolStripComboBox->SelectionStart = searchText->Length;
            toolStripComboBox->SelectionLength = sText->Length - searchText->Length;

          }
          else
          {
            toolStripComboBox->DroppedDown = false;
            toolStripComboBox->SelectionStart = searchText->Length;
          }
        }
        else
        {
          toolStripComboBox->DroppedDown = false;
          toolStripComboBox->Items->Clear();
        }
      }

这是我的示例实现。它已经搜索了非前缀,但我对代码不太满意,因为在设置自动完成模式时存在一些差异:

1)当您向上或向下按下项目的下拉菜单时,selectedIndexChanged 事件会触发,这与自动完成模式不同
2)还有更多的细微差别。

我真正想要的是它只会模仿建议中的自动完成模式,但它会搜索非前缀。

非常感谢任何示例代码、链接或建议。:)

4

1 回答 1

1

在这个间接但有用的样本的帮助下,我终于能够解决这个问题。

覆盖 Winforms ComboBox 自动完成建议规则
http://www.codeproject.com/Articles/3958/AC-auto-complete-combo-box
http://www.codeproject.com/Tips/631196/ComboBox-with-Suggest-Ability -基于子串-S

并通过以下方式selectedIndexChanged解决了这个问题:
当表单加载时停止组合框的 selectedIndexChanged 事件,并且
selectedIndexChanged 是自动触发的,而无需在 c# windows 应用程序的组合框中选择项目

综上所述,为了创建一个模仿自动完成模式的建议,不要仅仅基于前缀搜索,您需要订阅ToolStripComboBoxComboBox的几个事件。

以下是您需要创建和修改的事件:

toolStripComboBox_TextUpdate
toolStripComboBox_KeyDown
toolStripComboBox_DropDown
toolStripComboBox_ChangeCommit


在 TextUpdate() 上:

toolStripComboBox_TextUpdate(System::Object^  sender, System::EventArgs^  e) {
  String ^ searchText = toolStripComboBox->Text;
  toolStripComboBox->Items->Clear();

  if(searchText != "") {
    Regex ^ searchRegex = gcnew Regex("(?i).*"+searchText+".*");

    for(int i = 0; i<storageList->Count; i++) {
      Match ^ m = searchRegex->Match(storageList[i]);
      if(m->Value == storageList[i]) {
        toolStripComboBox->Items->Add(storageList[i]);
      }
    }

    if(toolStripComboBox->Items->Count > 0) {
      toolStripComboBox->DroppedDown = true;
      toolStripComboBox->Text = searchText;
      Cursor->Current = Cursors::Default;
    }
    else {
      toolStripComboBox->DroppedDown = false;
    }
    toolStripComboBox->SelectionStart = searchText->Length;  
  }
  else {
    toolStripComboBox->DroppedDown = false;
    toolStripComboBox->Items->Clear();
  }
}

TextUpdate总结:这个事件只是处理toolStripComboBox的匹配和填充以及下拉的状态


在 KeyDown() 上:

toolStripComboBox_KeyDown(System::Object^  sender, System::Windows::Forms::KeyEventArgs^  e) {
  String ^ searchText = toolStripComboBox->Text;
  if(e->KeyCode == Keys::Down || e->KeyCode == Keys::Up) {
    if(e->KeyCode == Keys::Down) {
      if(toolStripComboBox->SelectedIndex == -1 && toolStripComboBox->Items->Count > 0) {
             toolStripComboBox->SelectedIndex = 0;
      }
    }
    if(e->KeyCode == Keys::Up) {
      if(toolStripComboBox->SelectedIndex == -1 && toolStripComboBox->Items->Count > 0) {
        toolStripComboBox->SelectedIndex = toolStripComboBox->Items->Count - 1;
      }
    }
    keydownTxt->Text = Convert::ToString(toolStripComboBox->SelectedIndex);
  }
  if(e->KeyCode == Keys::Back) {
    toolStripComboBox->SelectionStart = searchText->Length;
  }
  if(e->KeyCode == Keys::Enter) {
    toolStripComboBox_ChangeCommit(sender, e);
  }
}

KeyDown 摘要:这会处理按下的特殊键,例如向上和向下箭头、退格键和回车键。请注意,当您按下回车键时会触发 ChangeCommit() 事件。发生这种情况是因为当您按下 Enter 时不会触发 ChangeCommit 事件,只能通过鼠标单击来触发。


在下拉():

toolStripComboBox_DropDown(System::Object^  sender, System::EventArgs^  e) {
  String ^ searchText = toolStripComboBox->Text;
  toolStripComboBox->SelectionStart = searchText->Length;
}

DropDown 摘要:它只是一个小修复,因为当DroppedDown属性设置为 时true,它会阻止 的可编辑部分ToolStripComboBox选择列表中的第一项。


在 ChangeCommit() 上: 因为我有这样的问题:
1) 当您向上或向下按下项目的下拉菜单时,selectedIndexChanged 事件会触发,这与自动完成模式不同,不会触发该问题
的解决方案是取消订阅SelectedIndexChanged并替换它带有一个事件处理程序ChangeCommit,该处理程序不是 中的方法,ToolStripComboBox而是以下方法ComboBox

this->toolStripComboBox->ComboBox->SelectionChangeCommitted += gcnew System::EventHandler(this, &Form1::toolStripComboBox_ChangeCommit);

在这个凶残的实施之后,YEEEY!我已经成功地模仿自动完成模式建议,建议项目只匹配文本中的子字符串..!!
这个问题也可以作为 Simple 的解决方案ComboBoxes
这个方法可能有点脏,所以其他人可以继承和覆盖事件,这样可以使代码更整洁。

于 2014-12-23T02:57:39.000 回答