2009-01-29 7 views
7

Gibt es eine einfache Möglichkeit, eine wechselseitige WPF-Datenbindung nach der letzten Änderung einige Millisekunden zu warten, bevor die Quelle mit dem neuen Eigenschaftswert aktualisiert wird?So verschieben Sie ein Update auf eine Bindung in WPF

Ich bin ein Filter-Feature für eine ListBox implementieren, wo ich ein Textfeld habe, und ich möchte den Inhalt der ListBox nach dem was ich tippe filtern. Ich verwende Datenbindung, um die Teile miteinander zu verbinden. Das Filtern der Liste kann ziemlich zeitaufwendig sein, deshalb möchte ich es nicht nach jedem eingegebenen Zeichen machen: daher meine Anfrage.

Ich habe Paul Stovells DelayBinding Extension verwendet (seine Site ist im Moment down, also kann ich mich nicht damit verbinden). Ich vermute jedoch, dass dies der Grund für einen Speicherverlust in meiner Anwendung ist (verursacht dadurch, dass Event-Handler nicht entfernt werden).

Hat sonst noch jemand andere Ideen?

+0

nur bestätigt, erlebte ich ähnliches Problem mit DelayBinding. Ich hatte eine MVVM-Shell-Anwendung, die ein StackPanel voller Menüschaltflächen und ein Haupt-ContentControl enthielt. Der ContentControl.Content wurde durch eine Eigenschaft in der Shell ViewModel festgelegt. Wenn ich jedoch ein UserControl geladen habe, das eine DelayBinding-Funktion enthielt, und dann den Inhalt wechselte, ging die Speicherbelegung gerade durch. Memory Profiler hat bestätigt, dass die alten Content UserControls vom GC nicht erfasst werden konnten. – LiamV

Antwort

2

Zuerst, um Ihre Frage zu beantworten, würde ich die UpdateSourceTrigger Bindungserweiterung hinzufügen, die Sie steuern lassen, wenn die Bindung aktualisiert wird. Versuchen Sie es zuerst mit LostFocus, aber es klingt so, als würden Sie sich für Explicit entscheiden.

Zweitens, wenn Ihre Filterung lange dauert, würde ich in der Verwendung von CollectionViewSource auf Ihrer ListBox suchen. Bea Stollnitz hat eine gute Grundierung darauf here und ich habe this blog post verwendet, um mir zu zeigen, wie man filtert. Als ich umgestiegen bin, habe ich einen enormen Geschwindigkeitsunterschied zu meiner anderen Implementierung bemerkt, obwohl sie die gleichen Filterfunktionen verwenden. Auch CollectionViewSource wird automatisch mit der Aktualisierung von gefilterten Elementen umgehen, wenn sich die Liste, an die Sie gebunden sind, sogar auf der Elementebene ändert, wenn Sie eine ObservableCollection binden (dies ist der ursprüngliche Grund für die Änderung von CollectionViewSource).

HTH

+0

Danke Bryan. Ich war auf UpdateSourceTrigger = Explicit aufmerksam, aber ich hatte gehofft, dass jemand eine fertige Lösung hätte (im Sinne von DelayBinding), die dafür sorgen würde, dass das Update nach einer Verzögerung ausgelöst wird. –

5

Ein wenig spät, um die Frage hier (nur wenige Jahre :) aber für jeden, der interessiert ist, hatte ich eine ähnliche Anforderung in einem Projekt so habe ich zwei Markup Erweiterungen DelayBindingExtension und DelayMultiBindingExtension genannt.

Sie funktionieren wie normal Bindings mit dem Zusatz, den Sie UpdateSourceDelay und/oder UpdateTargetDelay angeben können, die beide TimeSpan Eigenschaften sind. Ich habe auch verifiziert, dass es leckfrei ist (es nutzt die Eigenschaft geändert Callback einer Abhängigkeit Eigenschaft Bindung durch Vererbungskontext statt der DependencyPropertyDescriptor).

Beispiel für die Verwendung für eine DelayBinding

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

Und für einen 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> 

Quellcode und Beispielverwendung für DelayBinding und DelayMultiBinding kann here heruntergeladen werden.
Wenn Sie in die Details der Implementierung interessiert sind, können Sie es hier in meinem Blogbeitrag check out: DelayBinding and DelayMultiBinding with Source and Target delay

+1

Ich bin mir bewusst, dass dies eine alte Antwort ist, aber wenn Sie .NET Framework 4.5 verwenden, gibt es [eine Verzögerungseigenschaft] (http://msdn.microsoft.com/en-us/library/system.windows. data.bindingbase.delay.aspx) –

+0

Sieht aus wie alle hier zu spät, aber danke dafür, seine Verwendung ist perfekt. Meine Frage ist: Es sieht ziemlich schwer aus, beeinträchtigt es die Leistung nicht zu sehr? – Kilazur

+1

@Kilazur: Ich habe die Implementierung von diesem in einer Weile nicht angeschaut, aber es sollte keinen bemerkenswerten Einfluss auf die Leistung haben. Ich benutze es in fast jedem Projekt und habe nie einen Leistungsabfall bemerkt :-) –

13

Ich bin auch ein paar Jahre zu spät, aber wenn Sie WPF verwenden 4.5+ there is now an property genau für diese Zweck, es heißt Delay.

Beschreibung

Die Menge an Zeit in Millisekunden, die Bindungsquelle vor der Aktualisierung zu warten.

Anwendungsbeispiel

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