winforms - Autosearch personalizado de ToolStripCombobox en Visual C++
visual-c++ autocomplete (1)
Quiero implementar una caja de herramientas que se comporte como autocompletemode y se sugiera. No configuré el modo autocompletar, ya que solo encuentra elementos idénticos al prefijo.
Lo que quiero es que también pueda encontrar elementos en el cuadro combinado que tenga una subcadena, aunque no comience con eso .
lista de muestra:
Enero, febrero, marzo, abril, mayo, junio, julio, agosto, septiembre, octubre, noviembre, diciembre
Si escribo en el cuadro de herramientas de herramientas para "ber" , debería aparecer en el menú desplegable:
septiembre
octubre
noviembre
diciembre
respectivamente.
A partir de ahora, creé una lista separada que contiene los elementos:
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");
}
y agregué un evento TextUpdate para ToolStripCombobox:
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();
}
}
Esta es mi implementación de muestra. Ya busca el prefijo, pero no estoy del todo satisfecho con el código, ya que existen algunas diferencias cuando se establece el modo autocompletar en sugerir:
1) Al presionar una tecla hacia arriba o hacia abajo en el menú desplegable para los elementos, el evento selectedIndexChanged se dispara a diferencia del modo autocompletar que no funciona
2) Y muchas más diferencias menores.
Lo que realmente quiero es que simplemente imitará el modo autocompletar en sugerir, pero buscará sin prefijo ...
Todos los códigos, enlaces o sugerencias de muestra son muy apreciados. :)
Con la ayuda de estas muestras indirectas pero útiles, finalmente pude resolver este problema.
Sobrescribir formas de pago ComboBox Autocompletar Sugerir regla
http://www.codeproject.com/Articles/3958/AC-auto-complete-combo-box
http://www.codeproject.com/Tips/631196/ComboBox-with-Suggest-Ability-based-on-Substring-S
y con el problema de selectedIndexChanged
fue resuelto por esto:
Detener el evento selectedIndexChanged de comboBox de que se active cuando se carga el formulario y
El selectedIndexChanged se activa automáticamente sin seleccionar elementos en el cuadro combinado en la aplicación c # windows
Para resumir todo, para crear una imitación del modo de autocompletar, sugiera que no solo se base en búsquedas prefijadas, necesita suscribirse a varios eventos de ToolStripComboBox y ComboBox .
Estos son los eventos que necesita crear y modificar:
toolStripComboBox_TextUpdate
toolStripComboBox_KeyDown
toolStripComboBox_DropDown
toolStripComboBox_ChangeCommit
En 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();
}
}
Resumen de TextUpdate: este evento solo maneja la coincidencia y población de toolStripComboBox y el estado del desplegable
En 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);
}
}
Resumen de KeyDown: maneja las teclas especiales que se presionan como la flecha hacia arriba y hacia abajo, el retroceso y la tecla Intro ... observe que el evento ChangeCommit () se activó al presionar enter. esto sucede porque el evento ChangeCommit no se activa al presionar enter, solo con un clic del mouse.
En DropDown ():
toolStripComboBox_DropDown(System::Object^ sender, System::EventArgs^ e) {
String ^ searchText = toolStripComboBox->Text;
toolStripComboBox->SelectionStart = searchText->Length;
}
DropDown Summary: es solo una solución menor, ya que cuando la propiedad DroppedDown
se establece en true
, impide que la parte editable de ToolStripComboBox
seleccione el primer elemento en la lista.
En ChangeCommit (): dado que tengo un problema como este:
1) Al presionar una tecla hacia arriba o hacia abajo en el menú desplegable para los elementos, el evento selectedIndexChanged se dispara a diferencia del modo autocompletar que no funciona
La solución a esto es darse de baja del SelectedIndexChanged
y reemplazarlo con un controlador de eventos ChangeCommit
que no es un método en el ToolStripComboBox
pero es un método del ComboBox
:
this->toolStripComboBox->ComboBox->SelectionChangeCommitted += gcnew System::EventHandler(this, &Form1::toolStripComboBox_ChangeCommit);
¡Después de esta implementación asesina, YEEEY! He imitado con éxito el modo autocompletar sugiriendo que sugiera elementos que coincidan solo con una subcadena en el texto ...
Este problema también puede ser una solución para ComboBoxes
simples.
Este método puede estar un poco sucio, por lo que otros pueden heredar y anular los eventos para que el código sea más ordenado.