using Ninject;using ReactiveUI;using System;using System.Collections.Generic;namespace WeinCad.Controls{public class NinjectDependencyResolver : IMutableDependencyResolver{IKernel _kernel;public NinjectDependencyResolver(IKernel kernel){_kernel = kernel;}public void Register(Func<object> factory, Type serviceType, string contract = null){var r = _kernel.Bind(serviceType).ToMethod(context => factory());if (contract!=null){r.Named(contract);}}public object GetService(Type serviceType, string contract = null){if (contract!=null){return _kernel.Get(serviceType, contract);}else{return _kernel.Get(serviceType);}}public IEnumerable<object> GetServices(Type serviceType, string contract = null){if (contract!=null){return _kernel.GetAll(serviceType, contract);}else{return _kernel.GetAll(serviceType);}}public void Dispose(){_kernel.Dispose();}}public class NinjectToRx{public static IKernel SetupNinject(IKernel testKernel = null){var kernel = testKernel ?? CreateStandardKernel();// Set up NInject to do DIRxApp.MutableResolver = new NinjectDependencyResolver(kernel);//RxApp.Initialize();RxApp.MutableResolver.InitializeResolver();return kernel;}public static IKernel CreateStandardKernel(){return new StandardKernel();}}}
using System;using Ninject;using ReactiveUI;using ReactiveUI.Ext;using WeinCad.Controls.View;using WeinCad.Controls.ViewModel;using WeinCad.Data;using Weingartner.Controls;using Weingartner.Lens;using Weingartner.Numerics.Pump;namespace WeinCad.Controls{/// <summary>/// Singleton resources for the application/// </summary>public class ApplicationResources{/// <summary>/// The main undo stack for the application/// </summary>public MoineauSaveLoadViewModel MoineauSaveLoadViewModel { get; private set; }/// <summary>/// The main undo stack for the settings/// </summary>public UndoStack<SettingsType> RootSettings { get; private set; }public ApplicationResources(IIOService io){// Set up our data modelsMoineauSaveLoadViewModel = new MoineauSaveLoadViewModel( io, WeinCadFile.Default, WeinCadFile.Load, (stream, o) => o.ToJson(stream));RootSettings = SettingsStorage.Create();}}public class AppBootstrapper : ReactiveObject{public AppBootstrapper(IKernel testKernel = null, IRoutingState testRouter = null){var kernel = NinjectToRx.SetupNinject();kernel.Bind<IViewFor<MoineauPumpFormViewModel>>().To<MoineauPumpFormView>();kernel.Bind<IViewFor<Moineau3DMeshingViewModel>>().To<Moineau3DMeshingView>();kernel.Bind<IViewFor<MoineauManufacturingFormViewModel>>().To<MoineauManufacturingFormView>();kernel.Bind<IViewFor<MoineauMillingViewModel>>().To<MoineauMillingView>();kernel.Bind<IViewFor<DummyViewModel>>().To<DummyView>();kernel.Bind<IViewFor<MoineauPumpCorrectionsViewModel>>().To<MoineauPumpCorrectionsWindow>();kernel.Bind<IViewFor<MoineauSaveLoadViewModel>>().To<MoineauSaveLoadView>();kernel.Bind<IViewFor<MeasuringViewModel>>().To<MeasuringView>();kernel.Bind<IViewFor<MoineauDesignViewModel>>().To<MoineauDesignView>();kernel.Bind<IIOService>().To<IOService>();kernel.Bind<ApplicationResources>().ToSelf().InSingletonScope();kernel.Rebind<ILogger>().To<ConsoleLogger>().InSingletonScope();// Bind the units settings into the containervar unitsSettings = RxApp.DependencyResolver.GetService<ApplicationResources>().RootSettings.Focus(x => x.MeasurementSettings);kernel.Bind<ILens<MeasurementSettings>>().ToMethod(context => unitsSettings);// TODO: This is a good place to set up any other app// startup tasks, like setting the logging levelLogHost.Default.Level = LogLevel.Info;}}public class ConsoleLogger : ILogger{private LogLevel _Level;public void Write(string message, LogLevel logLevel){if(logLevel>=Level)Console.WriteLine(message);}public LogLevel Level{get{return _Level;}set{_Level = value;}}}}
public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, string propertyName, bool beforeChanged = false){Type type = sender.GetType();if (beforeChanged){LogHost.Log<DependencyObjectObservableForProperty>(this).Warn<string, string>("Tried to bind DO {0}.{1}, but DPs can't do beforeChanged. Binding as POCO object", type.FullName, propertyName);return new POCOObservableForProperty().GetNotificationForProperty(sender, propertyName, beforeChanged);}else{Func<DependencyProperty> dpFetcher = this.getDependencyPropertyFetcher(type, propertyName);if (dpFetcher != null)return Observable.Create<IObservedChange<object, object>>((Func<IObserver<IObservedChange<object, object>>, IDisposable>) (subj =>{DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(dpFetcher(), type);EventHandler ev = (EventHandler) ((o, e) => subj.OnNext((IObservedChange<object, object>) new ObservedChange<object, object>(){Sender = sender,PropertyName = propertyName}));dpd.AddValueChanged(sender, ev);return Disposable.Create((Action) (() => dpd.RemoveValueChanged(sender, ev)));}));LogHost.Log<DependencyObjectObservableForProperty>(this).Warn<string, string>("Tried to bind DO {0}.{1}, but DP doesn't exist. Binding as POCO object", type.FullName, propertyName);return new POCOObservableForProperty().GetNotificationForProperty(sender, propertyName, beforeChanged);}}
btw. I'm on reactiveui 5.4.0
Good idea. I'll try it tomorrow.
yy.GetAffinityForObject(typeof(WeinCad.Controls.View.Moineau3DMeshingView), "ViewModel", false);1xx.GetAffinityForObject(typeof(WeinCad.Controls.View.Moineau3DMeshingView), "ViewModel", false);4
public class ReactiveUserControl<ViewModelT> : UserControl, IViewFor<ViewModelT>where ViewModelT : class{
public UniformGrid DataContextHost { get; private set; }
public ReactiveUserControl(){
this.WhenAnyValue(x => x.ViewModel).BindTo(this, x => x.DataContextHost.DataContext);
}