2009-01-29 4 views
7

Existe-t-il un moyen facile de dire à une liaison de données WPF bidirectionnelle d'attendre quelques millisecondes après la dernière modification avant de mettre à jour la source avec la nouvelle valeur de propriété?Comment reporter une mise à jour vers une liaison dans WPF

J'implémente une fonctionnalité de filtre pour un ListBox où j'ai une zone de texte, et je veux filtrer le contenu de la ListBox en fonction de ce que je tape. J'utilise la liaison de données pour relier les pièces ensemble. Filtrer la liste peut prendre beaucoup de temps, donc je ne veux pas le faire après chaque caractère tapé: d'où ma demande. J'ai utilisé l'extension DelayBinding de Paul Stovell (son site est actuellement fermé, donc je ne peux pas le lier). Cependant, je soupçonne que c'est la cause d'une fuite de mémoire dans mon applicataion (causé par le fait qu'il ne supprime pas les gestionnaires d'événements).

Est-ce que quelqu'un d'autre a d'autres idées?

+0

Tout en confirmant, j'ai connu le même problème avec DelayBinding. J'avais une application shell MVVM qui contenait un StackPanel plein de boutons Menu et un ContentControl principal. ContentControl.Content a été défini par une propriété sur le ViewModel Shell, cependant si j'ai chargé un UserControl qui incluait un DelayBinding et a ensuite basculé le contenu, l'utilisation de la mémoire est passée à travers le toit. Memory Profiler a confirmé que les anciens Content UserControls ont été empêchés d'être collectés par le GC. – LiamV

Répondre

2

Tout d'abord, pour répondre à votre question, j'ajouterais l'extension de liaison UpdateSourceTrigger qui vous permettra de contrôler quand les mises à jour de liaison. Essayez LostFocus en premier, mais il semble que vous souhaitiez opter pour Explicit. Deuxièmement, si votre filtrage prend beaucoup de temps, je chercherais à utiliser CollectionViewSource sur votre ListBox. Bea Stollnitz a un bon début here et j'ai utilisé this blog post pour me montrer comment filtrer. Quand j'ai changé, j'ai remarqué une différence de vitesse énorme par rapport à mon autre implémentation, même si elles utilisent les mêmes fonctions de filtrage. En outre, CollectionViewSource gère automatiquement la mise à jour des éléments filtrés si la liste à laquelle vous êtes lié change, même au niveau de l'élément si vous liez un ObservableCollection (c'est la raison initiale pour laquelle je suis passé à CollectionViewSource).

HTH

+0

Merci Bryan. J'étais au courant de UpdateSourceTrigger = Explicit mais j'espérais que quelqu'un aurait une solution prête à l'emploi (sur le modèle de DelayBinding) qui prendrait soin de déclencher la mise à jour après un délai. –

5

Un peu plus tard à la question ici (quelques années :) mais pour toute personne intéressée par une exigence que j'avais même dans un projet, donc je créé deux extensions de balisage appelées DelayBindingExtension et DelayMultiBindingExtension.

Ils fonctionnent normalement Bindings avec l'addition que vous pouvez spécifier UpdateSourceDelay et/ou UpdateTargetDelay, les deux étant des propriétés TimeSpan. En outre, j'ai vérifié qu'il est sans fuite (il utilise le callback propertychanged d'une liaison de propriété de dépendance par le biais du contexte d'héritage plutôt que le DependencyPropertyDescriptor).

Exemple d'utilisation pour une DelayBinding

<TextBox Text="{db:DelayBinding Path=TextProperty, 
           UpdateSourceTrigger=PropertyChanged, 
           UpdateSourceDelay='00:00:01'}"/> 

Et pour une DelayMultiBinding

<cs:ColorSelector.SelectedColor> 
    <db:DelayMultiBinding Mode="TwoWay" 
          Converter="{StaticResource ColorConverter}" 
          UpdateSourceDelay="00:00:02" 
          UpdateTargetDelay="00:00:01"> 
     <Binding Path="Red" /> 
     <Binding Path="Green" /> 
     <Binding Path="Blue" /> 
    </db:DelayMultiBinding> 
</cs:ColorSelector.SelectedColor> 

Code Source et Exemple d'utilisation pour DelayBinding et DelayMultiBinding peut être téléchargé here.
Si vous êtes intéressé par les détails de mise en œuvre, vous pouvez consulter mon blog à ce sujet ici: DelayBinding and DelayMultiBinding with Source and Target delay

+1

Je suis conscient que c'est une vieille réponse, mais si vous utilisez .Net Framework 4.5, il y a [une propriété de délai] (http://msdn.microsoft.com/en-us/library/system.windows. data.bindingbase.delay.aspx) –

+0

On dirait que tout le monde est en retard ici, mais merci pour cela, son utilisation est parfaite. Ma question est: ça a l'air assez lourd, ça n'a pas trop d'impact sur la performance? – Kilazur

+1

@Kilazur: Je n'ai pas examiné la mise en œuvre de ce dans un certain temps, mais cela ne devrait pas avoir un impact notable sur les performances. Je l'utilise dans presque tous les projets et je n'ai jamais remarqué de baisse de performance de toute façon :-) –

13

Je suis aussi quelques années de retard, mais si vous utilisez WPF 4.5+ there is now an property exactement pour cette but, il est appelé Delay.

Description de

La quantité de temps, en millisecondes, d'attente avant la mise à jour de la source de liaison .

Exemple d'utilisation

<TextBlock Text="{Binding Name, Delay=500}"/> 
Questions connexes