2015-09-04 18 views
6

Ich versuche, den folgenden Code zu verstehen versuchen, reaktive Erweiterungenbeobachtbaren Muster auf reaktive Verlängerung

IObservable<string> textChangedObservable = 
      Observable.FromEventPattern<TextChangedEventArgs>(searchScrip, "TextChanged") 
       .Select(evt => ((TextBox) sender).Text); 

textChangedObservable.Subscribe(OnNext, OnCompleted); 

private void OnNext(string s) 
    { 
     System.Diagnostics.Debug.Print("OnNext " + s + "\n"); 
    } 

    private void OnCompleted() 
    { 
     System.Diagnostics.Debug.Print("OnCompleted " + "\n"); 
    } 

verwenden Wenn ich Suche innen das Eingabefeld eingeben, sieht die Ausgabe

  • OnNext SE
  • OnNext SEA
  • OnNext SEA
  • OnNext SEAR
  • OnNext SEAR
  • OnNext SEAR
  • OnNext SUCHTECHNOLOGIE
  • OnNext SUCHTECHNOLOGIE
  • OnNext SUCHTECHNOLOGIE
  • OnNext SUCHTECHNOLOGIE

    1. Warum ist "S" keine OnNext Auslösung?
    2. Warum wird OnCompleted nie aufgerufen?
    3. Warum wird der OnNext n-1 Mal auf dem n-ten Zeichen aufgerufen?
+0

keine einfache Frage, da die Klasse 'XamTextEditor' nicht mühelos zur Verfügung steht. Ich vermute, dass es etwas mit der Implementierung von 'RoutedPropertyChanged' zu tun haben könnte. – supertopi

+0

Eigentlich müssen Sie uns sagen, welche XAML-Elemente' searchScrip' und 'sender' sind. – supertopi

+0

Das Codebeispiel wurde geändert, um das wpf-Textfeld zu verwenden, um die Dinge einfach zu halten. Aber das Verhalten ist immer noch das Gleiche wie in den Fragen – asb

Antwort

3

Es scheint, dass Sie die Observable in Ihrem searchScrip_TextChanged Handler abonnieren.

Dies bedeutet, dass das erste Mal, dass searchScrip_TextChanged die S passiert schon aufgerufen wird, bevor Sie die beobachtbare verdrahtet haben. Also feuert es natürlich nicht.

Aber jetzt, da die S getroffen wird, haben Sie ein Abonnement, also wenn die E eingegeben wird, erhalten Sie eine einzige SE. Aber da der searchScrip_TextChanged Handler auch für den E aufgerufen wird, haben Sie jetzt zwei Abonnements für Ihr Observable.

Also, wenn die A eingegeben wird, erhalten Sie zwei SEA, weil Sie zwei Observablen haben. Aber wieder ist die searchScrip_TextChanged für die A aufgerufen, so dass Sie jetzt drei Observablen haben.

Etc, etc, etc.

Events vervollständigen nicht automatisch. Sie müssen die Abonnements manuell löschen, damit sie enden. Dies sollte sinnvoll sein, da dies mit normalen Event-Handlern zu tun hat, die Sie stoppen möchten.

Sie sollten Ihre Observable erstellen, wenn Ihr Formular geladen ist, damit es einmal erstellt wird.

Es soll wie folgt aussehen:

IObservable<string> textChangedObservable = 
     Observable.FromEventPattern<TextChangedEventArgs>(searchScrip, "TextChanged") 
      .Select(evt => searchScrip.Text); 

IDisposable subscription = 
    textChangedObservable 
     .Subscribe(
      s => Debug.Print("OnNext " + s + "\n"), 
      s => Debug.Print("OnCompleted\n")); 
-1

Vielleicht, weil Sie RoutedPropertyChangedEventArgs verwendet haben?

Was ist, wenn Sie PropertyChangedEventHandler verwenden?

Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
       h => yourModel.propertyChanged += h, 
       h => yourModel.propertyChanged -= h) 
      .Where(x => x.EventArgs.PropertyName = "your_property_name"); 
    } 
2

Das Problem hier hat wirklich nichts mit Rx zu tun.

1: Warum ist "S" keine OnNext Auslösung?

Da das TextChanged Ereignis, das Sie abonniert haben nicht Feuer auf dem ersten S.

2: Warum ist OnCompleted nie genannt?

Wenn Sie eine .NET-Ereignis als IObservable<T> wickeln, erhalten Sie nie OnError oder OnCompleted Benachrichtigungen. Es gibt kein Konzept für Fehler oder Abschluss mit einem .NET-Ereignis.

Wenn es zwei Ereignisse, eine für Werte und eine für den Abschluss, können Sie sie wie so kombinieren:

var values = Observable.FromEvent(...); 
var completion = Observable.FromEvent(...); 
var query = values.TakeUntil(completion); 

Jetzt query wird eine richtige OnCompleted Mitteilung ergeben.

3: Warum ist die OnNext genannt n-1 Mal auf den n-ten Zeichen?

Da die TextChanged Ereignis, das Sie abonniert haben, auf diese Weise ausgelöst.Wie von @ Kari-Antti darauf hingewiesen wurde, kann dies ein Nebeneffekt der Verwendung eines Ereignisses "geroutetes Merkmal" sein.

+0

1. Mein XAML für SearchScript ist und wenn ich einen Haltepunkt setzen, wird es ausgelöst für "S "bei der Implementierung" private void searchScrip_TextChanged (Objekt Absender, RoutedPropertyChangedEventArgs e) " – asb

+0

@asb Ich weiß nicht, wie Sie über das, was ich bereits gesagt habe, zu helfen. Das Observable wird nicht anders als das zugrunde liegende Ereignis emittieren. Es ist ein sehr einfacher Mechanismus. Also, was du sagst, dass das Observable und das Event nicht gleich funktionieren, widerspricht dem, was ich weiß, um wahr zu sein. –

+0

@TimothyShields - Er hat das Observable immer wieder abonniert - deshalb wird der OnNext auch "n-1" genannt. – Enigmativity