10
votes

Changer de manière dynamique la liste d'autocomplete de Textbox provoque l'accèsviolationException, des conseils?

Mon client souhaitait avoir une zone de texte sur le formulaire de clientèle de l'application, qui offre les fins applicables à un nom de rue démarré. Il commence à taper un nom de rue et la zone de texte propose une liste de rues qui commencent par la séquence de caractère qu'il saisit dans la zone de texte.

Je me suis dit: C'est d'accord, les textes de texte ont la propriété autocompletecustometTomsource et même si une liste de noms de rue commune sera plus longue qu'il ne pouvait être pré-rempli, je pouvais simplement frapper une base de données avec une requête, peupler un AutocompéquationCollection et montrez que pour l'utilisateur.

Maintenant voici la chose: si je fais la liste de remplissage sur chaque clé KeyPress / Keydown quoi que ce soit, le programme se bloque et jette une exceptionViolationException.

J'ai découvert que c'est parce que: Le contrôle est au milieu de la liste de la liste d'autocomplete lorsqu'il est modifié en même temps, entraînant le crash.

Lorsque vous actualisez la liste des autocomplets, le contrôle est recréé avec de nouveaux pointeurs. Événements du clavier et de la souris (KeyPress, Mouseover, Mouseleave, Mousehover) tentent de référencer les pointeurs de l'ancien contrôle qui sont maintenant invalides en mémoire entraînant une violation d'accès à la mémoire.

La mise en œuvre de la mise sous-jacente automatique ne permet pas de modifier l'objet de la liste de candidats autocompressé une fois qu'il a été défini sur une fenêtre. Pour permettre la modification de la liste, WinForms détruit le contrôle d'édition ou le comboquox et le recréère. Cela provoque une exception si le contrôle sous-jacent est détruit alors que la fenêtre Autocomplecte l'utilise toujours.

J'ai lu à ce sujet sur MSDN , leur résolution:

Ne modifiez pas la liste des candidats autocompressé de manière dynamique lors d'événements clés.

J'ai aussi tout essayé de Ce thread

Alors, comment puis-je faire ce travail, si j'insiste pour offrir les noms de rue applicables KeyPress-by-KeyPress?

note : Je sais que vous pouvez le faire en créant un contrôle personnalisé et tel, mais peut-il être fait avec une magie de codage pure?


4 commentaires

Pourquoi ne peuplez-vous pas simplement la liste une fois de votre base de données, y compris chaque article ? Est-ce viable?


"Faire un contrôle WPF et l'utiliser dans votre projet WinForms" ..


@Minitech bien, je suppose que c'est une façon de le faire, mais en chargement de 10 000 lignes chaque fois que le client veut vérifier sur un client ... Je ne sais pas ce que je ressens à ce sujet ... je devrais peut-être demander à certains professionnels ici sur le chargement de nombreuses données sur le spectacle. Il y a une chance que le client ne souhaite même pas éditer la boîte, copier simplement le nom de la rue ou quelque chose. En tant que mesure temporaire, cela pourrait fonctionner, mais y a-t-il un moyen de le faire comme nous voulions à l'origine?


@Andris: Eh bien, essayez-le et voyez à quel point c'est rapide ... Je pense aussi que vous pouvez le lier à une base de données et le laisser le faire lui-même, mais je ne suis pas capable d'essayer cela maintenant.


6 Réponses :


4
votes

La manière dont nous avons résolu ce problème dans notre application (où nous devons choisir d'éventuellement 100 000 articles) consistait à cautionnement sur la fonctionnalité automatique et à utiliser une combinaison de ComboBox.

Nous utilisons l'infragisme ComboBox, mais je Simprimez que la Standard Windows One fonctionnerait également.

L'astuce ici consiste à utiliser le ComboBox lui-même, en mode déroulant, en tant que liste autocomplete et de la populer comme des types d'utilisateurs.

Voici la logique que nous utilisons: xxx

en raison du grand nombre d'éléments, nous ne commençons pas à rechercher jusqu'à ce que l'utilisateur ait entré 4 caractères, mais c'est juste Notre mise en œuvre.


1 commentaires

Je viens d'utiliser les Winforms Combobox avec les suggestions de Compacents_Tech et mon formulaire fonctionne bien maintenant.



3
votes

C'est possible !!! Environ 3 heures de recherche et selon les informations de ce message que j'ai trouvé une solution. Vous devez supprimer presque tous les éléments d'Autocompletecustomesource (ou Combobox.items), puis Addrange () et finaly Supprimer 0-Index Item: XXX

Mais cette méthode est trop lente (en temps autocomplete), Peut-être que vous devez éliminer les éléments un-par-un. Désolé pour mon anglais.


1 commentaires

Cela fonctionne assez bien. J'ai dû ajouter un chèque que les articles ont un élément supplémentaire comparé à pour éviter un problème lorsque des éléments étaient vides avant ma mise à jour, ne vous aviez pas plus de problèmes après cela.



1
votes

Créer une variable privée en dehors de votre événement clé qui conserve toutes vos données de collection automatique.

        Dim names As String() = GetSuggested() //get your data from your source

        Dim namesToAdd As New List(Of String)

        For Each name As String In names
            If Not dataAutocompleteCollection.Contains(name) Then
                namesToAdd.Add(name)
            End If
        Next
        dataAutocompleteCollection.AddRange(namesToAdd.ToArray)

        If ctr_Data.AutoCompleteCustomSource.Count = 0 Then
            ctr_Data.AutoCompleteCustomSource = dataAutocompleteCollection 
        End If
  • autocompletemode ne doit pas être réglé sur Aucun Li>
  • Autocompéquation doit être à la gentillesse li> ul> p>


0 commentaires

0
votes
On general
Dim textme as string

On textchange
If textme =text1.text then exit sub
Textme=text1.text
Text1.autocompletecustomesource.clear
Text1.autocompletecustomesource.add ...

1 commentaires

Même si cela pourrait éventuellement être la bonne réponse, veuillez ajouter un commentaire à votre code pour une meilleure chance d'être accepté.



1
votes

J'avais le même problème jusqu'à ce que je fais retrouvais, vous deviez modifier l'autocompéquation à aucun avant d'avoir ajouté tous les articles que vous souhaitez, puis retournez-le à la gentillestauration après avoir terminé. Voici le code que j'ai utilisé ci-dessous. Veuillez excuser l'énoncé SQL car nous construisons un fichier DLL de wrapper pour faciliter les demandes SQL. XXX


0 commentaires

1
votes

tandis que 6 ans - cette question ne pose aucune réponse réelle ou au moins acceptée; Je vais donc ajouter mes deux cents sur la façon dont j'ai surmonté ce problème.

Qu'est-ce qui provoque cette erreur?

L'erreur se produit lorsque vous modifiez de manière dynamique les données autocompletstringCollection () les données tandis que Il est toujours attaché à un objet (c.-à-d. La zone de texte) que Visual Studio ne parviendra pas à disposer des données de la mémoire - et donc lors de la réaffectation, il tombe dans un tas et jette une erreur.

la solution de contournement < / h2>

tandis que vous pouvez implémenter un système pour attraper ces erreurs et les cacher finalement de l'utilisateur final; L'erreur sous-jacente survient toujours, c'est loin de la meilleure pratique.

La réponse évidente ici est d'abandonner la modification de la source à la volée; Bien que cela ne soit pas toujours possible - en particulier lorsqu'une application s'appuie sur un changement source au travail comme prévu.

Chaque fois que vous devez changer la source à la volée; Vous devriez placer le code suivant avant , vous modifiez la source. xxx

une fois que vous avez repeuplé la source à l'aide de autocompletringcollection () Ensuite, vous devriez revenir à la zone de texte à une source personnalisée; xxx

en faisant cela; Vous empêcherez l'erreur de se produire!

Modifier: occasionnellement, pour certains utilisateurs, vous devez constater que vous devez vider la collection de chaînes complète automatique avant de ré-attribuer de nouvelles valeurs - Ceci peut être réalisé en l'attribuant à null puis à nouveau renouveloir!


3 commentaires

Je pense que tu veux dire 6 ans, pas 6 mois


Et toujours un problème comme une décennie plus tard! > Ajout de merci cependant, il est toujours utile de comprendre pourquoi l'erreur se produit.


Oh dieu..Comment à ce sujet que diable? :