Skip to content

Instantly share code, notes, and snippets.

@JohanLarsson
Last active January 3, 2016 17:09
Show Gist options
  • Save JohanLarsson/8493887 to your computer and use it in GitHub Desktop.
Save JohanLarsson/8493887 to your computer and use it in GitHub Desktop.
[Test]
public void ReactiveTest()
{
var c = new MyClass();
c.ToTrackingObservable(x => x.Name)
.Subscribe(x => Console.WriteLine("New: {0}, old: {1}", x.CurrentValue, x.PreviousValue));
string[] names = {"Johan", "Max", "Erik"};
foreach (var name in names)
{
c.Name = name;
}
}
class MyClass : INotifyPropertyChanged
{
private string _name;
private int _age;
public string Name
{
get { return _name; }
set
{
if (value == _name) return;
_name = value;
OnPropertyChanged();
}
}
public int Age
{
get { return _age; }
set
{
if (value == _age) return;
_age = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public class PropertyChangedEventArgsTracking<TSource, TProperty> : PropertyChangedEventArgs<TSource, TProperty>
{
public PropertyChangedEventArgsTracking(TSource sender, TProperty currentValue, TProperty previousValue, string propertyName)
: base(sender, currentValue, propertyName)
{
PreviousValue = previousValue;
}
public TProperty PreviousValue { get; private set; }
}
using System.ComponentModel;
public class PropertyChangedEventArgs<TSource, TProperty> : PropertyChangedEventArgs
{
public PropertyChangedEventArgs(TSource sender, TProperty currentValue, string propertyName)
: base(propertyName)
{
Sender = sender;
CurrentValue = currentValue;
}
public TSource Sender { get; private set; }
public TProperty CurrentValue { get; private set; }
}
using System;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reactive;
using System.Reactive.Linq;
using Misc;
public static class ReactiveExt
{
public static IObservable<EventPattern<PropertyChangedEventArgs>> ToObservable<TNotifier, TProperty>(this TNotifier source,
Expression<Func<TNotifier, TProperty>> property) where TNotifier : INotifyPropertyChanged
{
string name = ((MemberExpression)property.Body).Member.Name;
var observable = source
.ToObservable()
.Where(e => e.EventArgs.PropertyName == name);
return observable;
}
public static IObservable<PropertyChangedEventArgsTracking<TNotifier, TProperty>> ToTrackingObservable<TNotifier, TProperty>(this TNotifier source,
Expression<Func<TNotifier, TProperty>> property) where TNotifier : INotifyPropertyChanged
{
Func<TNotifier, TProperty> getter = property.Compile();
var observable = source.ToObservable(property)
.Scan(
new PropertyChangedEventArgsTracking<TNotifier, TProperty>(source,
default(TProperty), default(TProperty), ""),
(acc, cur) =>
new PropertyChangedEventArgsTracking<TNotifier, TProperty>(source,
getter(source), acc.CurrentValue, acc.PropertyName));
return observable;
}
public static IObservable<EventPattern<PropertyChangedEventArgs>> ToObservable(this INotifyPropertyChanged source)
{
IObservable<EventPattern<PropertyChangedEventArgs>> observable = Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
x => source.PropertyChanged += x,
x => source.PropertyChanged -= x);
return observable;
}
// public static IObservable<TProperty> ToObservable<TNotifier, TProperty>(this OcNpcListener<TNotifier> source,
//Expression<Func<TNotifier, TProperty>> property) where TNotifier : INotifyPropertyChanged
// {
// string name = ((MemberExpression)property.Body).Member.Name;
// Func<TNotifier, TProperty> getter = property.Compile();
// IObservable<TProperty> observable = source.ToObservable()
// .Select(x => x.EventArgs)
// .Where(x => x.PropertyName == name)
// .Select(x => getter((TNotifier)x.Child));
// return observable;
// }
// public static IObservable<EventPattern<ChildPropertyChangedEventArgs>> ToObservable<T>(this OcNpcListener<T> source) where T : INotifyPropertyChanged
// {
// IObservable<EventPattern<ChildPropertyChangedEventArgs>> observable = Observable
// .FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
// x => source.PropertyChanged += x,
// x => source.PropertyChanged -= x)
// .Select(x => new EventPattern<ChildPropertyChangedEventArgs>(x.Sender, (ChildPropertyChangedEventArgs)x.EventArgs));
// return observable;
// }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment