using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Runtime.CompilerServices;
public static void Main()
Console.WriteLine("Hello World");
public partial class HostContainer
public partial class Host : INotifyPropertyChanged
private HostContainer.Host.ViewModelHost _viewModel;
public event PropertyChangedEventHandler PropertyChanged;
set => RaiseAndSetIfChanged(ref _value, value);
public HostContainer.Host.ViewModelHost ViewModel
set => RaiseAndSetIfChanged(ref _viewModel, value);
public IDisposable GetTwoWayBindSubscription()
return this.Bind(ViewModel, x => x.Value, x => x.Value);
public IObservable<object> GetWhenChangedViewModelObservable()
return this.WhenChanged(x => x.ViewModel);
public IObservable<object> GetWhenChangedObservable()
return this.WhenChanged(x => x.Value);
protected void RaiseAndSetIfChanged<T>(ref T fieldValue, T value, [CallerMemberName] string propertyName = null)
if (EqualityComparer<T>.Default.Equals(fieldValue, value))
OnPropertyChanged(propertyName);
protected virtual void OnPropertyChanged(string propertyName)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
protected internal partial class ViewModelHost : INotifyPropertyChanged
private ViewModelHost _child;
public event PropertyChangedEventHandler PropertyChanged;
set => RaiseAndSetIfChanged(ref _value, value);
internal ViewModelHost Child
set => RaiseAndSetIfChanged(ref _child, value);
public IObservable<object> GetWhenChangedObservable()
return this.WhenChanged(x => x.Value);
protected void RaiseAndSetIfChanged<T>(ref T fieldValue, T value, [CallerMemberName] string propertyName = null)
if (EqualityComparer<T>.Default.Equals(fieldValue, value))
OnPropertyChanged(propertyName);
protected virtual void OnPropertyChanged(string propertyName)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public partial class HostContainer
public partial class Host
protected internal IObservable<HostContainer.Host.ViewModelHost> WhenChanged( Expression<Func<HostContainer.Host, HostContainer.Host.ViewModelHost>> propertyExpression, [CallerMemberName]string callerMemberName = null, [CallerFilePath]string callerFilePath = null, [CallerLineNumber]int callerLineNumber = 0) =>Observable.Create<HostContainer.Host.ViewModelHost>(observer=>
if ( this == null) return Disposable.Empty;
observer.OnNext(this.ViewModel);
PropertyChangedEventHandler handler = ( sender, e) =>
if ( e.PropertyName == "ViewModel")
observer.OnNext(this.ViewModel);
this.PropertyChanged+=handler;
return Disposable.Create(( Parent: this, Handler: handler) , x=>this.PropertyChanged-=x.Handler);
public IObservable<string> WhenChanged( Expression<Func<HostContainer.Host, string>> propertyExpression, [CallerMemberName]string callerMemberName = null, [CallerFilePath]string callerFilePath = null, [CallerLineNumber]int callerLineNumber = 0) =>Observable.Create<string>(observer=>
if ( this == null) return Disposable.Empty;
observer.OnNext(this.Value);
PropertyChangedEventHandler handler = ( sender, e) =>
if ( e.PropertyName == "Value")
observer.OnNext(this.Value);
this.PropertyChanged+=handler;
return Disposable.Create(( Parent: this, Handler: handler) , x=>this.PropertyChanged-=x.Handler);
public partial class HostContainer
public partial class Host
protected internal partial class ViewModelHost
protected internal IObservable<string> WhenChanged( Expression<Func<HostContainer.Host.ViewModelHost, string>> propertyExpression, [CallerMemberName]string callerMemberName = null, [CallerFilePath]string callerFilePath = null, [CallerLineNumber]int callerLineNumber = 0) =>Observable.Create<string>(observer=>
if ( this == null) return Disposable.Empty;
observer.OnNext(this.Value);
PropertyChangedEventHandler handler = ( sender, e) =>
if ( e.PropertyName == "Value")
observer.OnNext(this.Value);
this.PropertyChanged+=handler;
return Disposable.Create(( Parent: this, Handler: handler) , x=>this.PropertyChanged-=x.Handler);
public partial class HostContainer
public partial class Host
protected internal IDisposable Bind( HostContainer.Host.ViewModelHost targetObject, Expression<Func<HostContainer.Host, string>> fromProperty, Expression<Func<HostContainer.Host.ViewModelHost, string>> toProperty, IScheduler scheduler = null, [CallerMemberName]string callerMemberName = null, [CallerFilePath]string callerFilePath = null, [CallerLineNumber]int callerLineNumber = 0)
IObservable<string> hostObs = this.WhenChanged(fromProperty, callerMemberName, callerFilePath, callerLineNumber);
IObservable<string> targetObs = targetObject.WhenChanged(toProperty, callerMemberName, callerFilePath, callerLineNumber).Skip(1);
scheduler=scheduler ?? ImmediateScheduler.Instance;
return new CompositeDisposable(hostObs.Subscribe(x=>targetObject.Value=x), targetObs.Subscribe(x=>this.Value=x));