2009-11-10 6 views
1

Je tente de rechercher une zone de liste déroulante en fonction du texte entré via un événement de clavier. La recherche fonctionne et le résultat correct est sélectionné mais je n'arrive pas à obtenir le scrollToIndex pour trouver le bon élément qui devrait être le résultat trouvé (i). Il fait défiler jusqu'à la dernière lettre entrée qui je crois est le comportement par défaut d'une liste déroulante. Je pense que je fais référence à la cible de l'événement de manière incorrecte. Débutant déchirer mes cheveux. Pouvez-vous aider? Je vous remercie. Voici la fonction:Flex 3 scrollToIndex Aide

private function textin(event:KeyboardEvent):void 
{ 

var combo:ComboBox = event.target as ComboBox; 

var source:XMLListCollection = combo.dataProvider as XMLListCollection; 

str += String.fromCharCode(event.charCode); 

if (str=="") { 
    combo.selectedIndex = 0; 
} 

for (var i:int=0; i<source.length; i++) { 

    if (source[i][email protected](new RegExp("^" + str, "i"))) { 
    combo.selectedIndex = i; 
    event.target.scrollToIndex(i); 
    break; 
    } 

} 
} 

contrôle:

<mx:ComboBox keyDown="textin(event);" id="thislist" change="processForm();" dataProvider="{xmllist}"/> 
+0

Pourquoi une zone de liste déroulante est-elle la cible d'un événement de clavier dont vous saisissez un code de charte? Êtes-vous sûr que c'est l'event.target? Peut-être que si vous postez le reste du code, je peux vous aider plus. –

Répondre

1

Si event.target est un mx.control.ComboBox alors il n'a pas une méthode scrollToIndex, qui est une méthode définie dans mx.controls.ListBase, que le ComboBox ne hérite de. Vérifiez la référence de l'API pour le ComboBox. Quel est exactement le résultat que vous essayez d'atteindre ici? Si vous définissez l'index sélectionné d'un ComboBox, il doit afficher l'élément à cet index.

EDIT: Essayez d'obtenir le remplacement de event.target.scrollToIndex(i) (qui devrait jeter une erreur de toute façon) et le remplacer par event.stopImmediatePropagation(). Cela devrait empêcher tout gestionnaire de clé par défaut de déclencher et de surcharger votre gestionnaire d'événements.

+0

Merci, Ryan. L'élément selectedIndex affiche l'élément à cet index avec succès. Je pensais avoir lu quelque part que ComboBox avait hérité de ListBase. J'essaie de montrer la liste raisonnable ci-dessous l'index selectedI. Donc, si Anagramme est l'élément sélectionné dans une liste de (Ligne aérienne, Anagaram, Ant, Apple, Orange, Poire, Nukes) alors Ant serait l'élément suivant dans le parchemin lorsque vous entrez "n" pas Nukes. – Kerri

+0

Je pense que je comprends ce que vous essayez d'accomplir ici. Dans quel contrôle l'utilisateur entre-t-il le texte? Publiez du code montrant les contrôles et comment vous y avez attaché les gestionnaires d'événements. Si vous pouviez corriger la mise en forme du code que vous avez déjà posté, ce serait bien aussi. Ajoutez simplement des espaces avant les lignes qui ne sont pas formatées correctement. –

+0

J'ai essayé de le nettoyer un peu et à la fin j'ai ajouté ce que le contrôle ressemble. Essentiellement, j'essaie de permettre à l'utilisateur de rechercher et parcourir une longue liste via une liste déroulante. Une fois sélectionné, il traite le formulaire. Une fois que la liste déroulante est fermée et rouverte, la liste est dans le bon ordre sous l'élément sélectionné comme prévu. – Kerri

0

Voici une solution, basée sur le code de Kerri et les suggestions de Ryan Lynch. Le crédit va alors.

Cela fonctionne pour moi, donc je vais laisser le code complet ici pour les générations futures. :)

import com.utils.StringUtils; 

import flash.events.KeyboardEvent; 
import flash.events.TimerEvent; 
import flash.utils.Timer; 

import mx.collections.ArrayCollection; 
import mx.controls.ComboBox; 

public class ExtendedComboBox extends ComboBox 
{ 
    private var mSearchText : String = ""; 

    private var mResetStringTimer : Timer; 

    public function ExtendedComboBox() 
    { 
     super(); 

     mResetStringTimer = new Timer(1000); 
     mResetStringTimer.addEventListener(TimerEvent.TIMER, function() : void { mResetStringTimer.stop(); mSearchText = ""; }); 
    }  

    override protected function keyDownHandler(aEvent : KeyboardEvent):void 
    { 
     if(aEvent.charCode < 32) 
     { 
      super.keyDownHandler(aEvent); 
      return; 
     } 

     var lComboBox : ComboBox = aEvent.target as ComboBox; 

     var lDataProvider : ArrayCollection = lComboBox.dataProvider as ArrayCollection; 

     mSearchText += String.fromCharCode(aEvent.charCode); 

     if (StringUtils.IsNullOrEmpty(mSearchText)) 
     { 
      lComboBox.selectedIndex = 0; 
      aEvent.stopImmediatePropagation(); 
      return; 
     } 

     if(mResetStringTimer.running) 
      mResetStringTimer.reset(); 

     mResetStringTimer.start(); 

     for (var i : int = 0; i < lDataProvider.length; i++) 
     {    
      if (lDataProvider[i].label.match(new RegExp("^" + mSearchText, "i"))) 
      { 
       lComboBox.selectedIndex = i; 
       aEvent.stopImmediatePropagation(); 
       break; 
      } 
     } 
    } 
} 

Cette solution attend un ArrayCollection comme fournisseur de données et un champ nommé « label » pour faire la recherche. Vous pouvez créer une variable pour stocker le nom du champ, et l'utiliser comme ceci:

lDataProvider[i][FIELD_NAME_HERE].match(new RegExp("^" + mSearchText, "i")) 

Amusez-vous!