/// <summary> /// Given a fully filled-out IObservedChange object, SetValueToProperty /// will apply it to the specified object (i.e. it will ensure that /// target.property == This.GetValue() and "replay" the observed change /// onto another object) /// </summary> /// <param name="target">The target object to apply the change to.</param> /// <param name="property">The target property to apply the change to.</param> public static void SetValueToProperty <TSender, TValue, TTarget>( this IObservedChange <TSender, TValue> This, TTarget target, Expression <Func <TTarget, TValue> > property) { Reflection.SetValueToPropertyChain(target, Reflection.ExpressionToPropertyNames(property), This.GetValue()); }
/// <summary> /// WhenAny allows you to observe whenever one or more properties on an /// object have changed, providing an initial value when the Observable /// is set up, unlike ObservableForProperty(). Use this method in /// constructors to set up bindings between properties that also need an /// initial setup. /// </summary> public static IObservable <TRet> WhenAnyDynamic <TSender, TRet>(this TSender This, string[] property1, string[] property2, string[] property3, Func <IObservedChange <TSender, object>, IObservedChange <TSender, object>, IObservedChange <TSender, object>, TRet> selector) { var slot1 = new ObservedChange <TSender, object>() { Sender = This, PropertyName = String.Join(".", property1), }; object slot1Value = default(object); slot1.TryGetValue(out slot1Value); slot1.Value = slot1Value; IObservedChange <TSender, object> islot1 = slot1; var slot2 = new ObservedChange <TSender, object>() { Sender = This, PropertyName = String.Join(".", property2), }; object slot2Value = default(object); slot2.TryGetValue(out slot2Value); slot2.Value = slot2Value; IObservedChange <TSender, object> islot2 = slot2; var slot3 = new ObservedChange <TSender, object>() { Sender = This, PropertyName = String.Join(".", property3), }; object slot3Value = default(object); slot3.TryGetValue(out slot3Value); slot3.Value = slot3Value; IObservedChange <TSender, object> islot3 = slot3; return(Observable.Create <TRet>(subject => { subject.OnNext(selector(islot1, islot2, islot3)); return Observable.Merge(This.ObservableForProperty(property1).Do(x => { lock (slot1) { islot1 = x.fillInValue(); } }).Select(x => selector(islot1, islot2, islot3)), This.ObservableForProperty(property2).Do(x => { lock (slot2) { islot2 = x.fillInValue(); } }).Select(x => selector(islot1, islot2, islot3)), This.ObservableForProperty(property3).Do(x => { lock (slot3) { islot3 = x.fillInValue(); } }).Select(x => selector(islot1, islot2, islot3))).Subscribe(subject); })); }
/// <summary> /// Given a fully filled-out IObservedChange object, SetValueToProperty /// will apply it to the specified object (i.e. it will ensure that /// target.property == This.GetValue() and "replay" the observed change /// onto another object) /// </summary> /// <param name="target">The target object to apply the change to.</param> /// <param name="property">The target property to apply the change to.</param> internal static void SetValueToProperty <TSender, TValue, TTarget>( this IObservedChange <TSender, TValue> This, TTarget target, Expression <Func <TTarget, TValue> > property) { Reflection.TrySetValueToPropertyChain(target, Reflection.Rewrite(property.Body).GetExpressionChain(), This.GetValue()); }
private void OnDelegateChanging(IObservedChange <ViewModel, IUGCanvasViewDelegate> oldValues) { if (oldValues.Value is IDisposable disposable) { disposable.Dispose(); } }
/// <summary> /// Based on a list of Expressions get a IObservedChanged for the value /// of the last property in the chain if possible. /// The Expressions are property chains. Eg Property1.Property2.Property3 /// The method will make sure that each Expression can get a value along the way /// and get each property until each expression is evaluated. /// </summary> /// <param name="changeValues">A IObservedChanged for the value.</param> /// <param name="current">The object that starts the property chain.</param> /// <param name="expressionChain">A list of expressions which will point towards a property or field.</param> /// <returns>If the value was successfully retrieved or not.</returns> public static bool TryGetAllValuesForPropertyChain(out IObservedChange <object, object>[] changeValues, object current, IEnumerable <Expression> expressionChain) { int currentIndex = 0; var expressions = expressionChain.ToList(); changeValues = new IObservedChange <object, object> [expressions.Count()]; foreach (Expression expression in expressions.SkipLast(1)) { if (current == null) { changeValues[currentIndex] = null; return(false); } var sender = current; current = GetValueFetcherOrThrow(expression.GetMemberInfo())(current, expression.GetArgumentsArray()); changeValues[currentIndex] = new ObservedChange <object, object>(sender, expression, current); currentIndex++; } if (current == null) { changeValues[currentIndex] = null; return(false); } Expression lastExpression = expressions.Last(); changeValues[currentIndex] = new ObservedChange <object, object>(current, lastExpression, GetValueFetcherOrThrow(lastExpression.GetMemberInfo())(current, lastExpression.GetArgumentsArray())); return(true); }
/// <summary> /// WhenAny allows you to observe whenever one or more properties on an /// object have changed, providing an initial value when the Observable /// is set up, unlike ObservableForProperty(). Use this method in /// constructors to set up bindings between properties that also need an /// initial setup. /// </summary> public static IObservable <TRet> WhenAny <TSender, TRet, T1, T2>(this TSender This, Expression <Func <TSender, T1> > property1, Expression <Func <TSender, T2> > property2, Func <IObservedChange <TSender, T1>, IObservedChange <TSender, T2>, TRet> selector) where TSender : IReactiveNotifyPropertyChanged { var slot1 = new ObservedChange <TSender, T1>() { Sender = This, PropertyName = String.Join(".", RxApp.expressionToPropertyNames(property1)), }; T1 slot1Value = default(T1); slot1.TryGetValue(out slot1Value); slot1.Value = slot1Value; IObservedChange <TSender, T1> islot1 = slot1; var slot2 = new ObservedChange <TSender, T2>() { Sender = This, PropertyName = String.Join(".", RxApp.expressionToPropertyNames(property2)), }; T2 slot2Value = default(T2); slot2.TryGetValue(out slot2Value); slot2.Value = slot2Value; IObservedChange <TSender, T2> islot2 = slot2; return(Observable.Create <TRet>(subject => { subject.OnNext(selector(islot1, islot2)); return Observable.Merge( This.ObservableForProperty(property1).Do(x => { lock (slot1) { islot1 = x.fillInValue(); } }).Select(x => selector(islot1, islot2)), This.ObservableForProperty(property2).Do(x => { lock (slot2) { islot2 = x.fillInValue(); } }).Select(x => selector(islot1, islot2)) ).Subscribe(subject); })); }
/// <summary> /// Returns the name of a property which has been changed. /// </summary> /// <typeparam name="TSender">The sender type.</typeparam> /// <typeparam name="TValue">The value type.</typeparam> /// <param name="item">The observed change.</param> /// <returns> /// The name of the property which has changed. /// </returns> public static string GetPropertyName <TSender, TValue>(this IObservedChange <TSender, TValue> item) { if (item is null) { throw new ArgumentNullException(nameof(item)); } return(Reflection.ExpressionToPropertyNames(item.Expression)); }
/// <summary> /// Returns the current value of a property given a notification that /// it has changed. /// </summary> /// <returns>The current value of the property</returns> public static TValue GetValue <TSender, TValue>(this IObservedChange <TSender, TValue> This) { TValue ret; if (!This.TryGetValue(out ret)) { throw new Exception(String.Format("One of the properties in the expression '{0}' was null", This.GetPropertyName())); } return(ret); }
/// <summary> /// Attempts to return the current value of a property given a /// notification that it has changed. If any property in the /// property expression is null, false is returned. /// </summary> /// <param name="changeValue">The value of the property /// expression.</param> /// <returns>True if the entire expression was able to be followed, /// false otherwise</returns> internal static bool TryGetValue <TSender, TValue>(this IObservedChange <TSender, TValue> This, out TValue changeValue) { if (!Equals(This.Value, default(TValue))) { changeValue = This.Value; return(true); } return(Reflection.TryGetValueForPropertyChain(out changeValue, This.Sender, This.Expression.GetExpressionChain())); }
/// <summary> /// Returns the current value of a property given a notification that /// it has changed. /// </summary> /// <typeparam name="TSender">The sender.</typeparam> /// <typeparam name="TValue">The changed value.</typeparam> /// <param name="item"> /// The <see cref="IObservedChange{TSender, TValue}"/> instance to get the value of. /// </param> /// <returns> /// The current value of the property. /// </returns> public static TValue?GetValueOrDefault <TSender, TValue>(this IObservedChange <TSender, TValue> item) { if (item is null) { throw new ArgumentNullException(nameof(item)); } if (!item.TryGetValue(out var returnValue)) { return(default);
/// <summary> /// Returns the current value of a property given a notification that /// it has changed. /// </summary> /// <typeparam name="TSender">The sender.</typeparam> /// <typeparam name="TValue">The changed value.</typeparam> /// <param name="this"> /// The <see cref="IObservedChange{TSender, TValue}"/> instance to get the value of. /// </param> /// <returns> /// The current value of the property. /// </returns> public static TValue GetValue <TSender, TValue>(this IObservedChange <TSender, TValue> @this) { TValue ret; if ([email protected](out ret)) { throw new Exception($"One of the properties in the expression '{@this.GetPropertyName()}' was null"); } return(ret); }
/// <summary> /// Attempts to return the current value of a property given a /// notification that it has changed. If any property in the /// property expression is null, false is returned. /// </summary> /// <param name="changeValue">The value of the property /// expression.</param> /// <returns>True if the entire expression was able to be followed, /// false otherwise</returns> public static bool TryGetValue <TSender, TValue>(this IObservedChange <TSender, TValue> This, out TValue changeValue) { if (!Equals(This.Value, default(TValue))) { changeValue = This.Value; return(true); } object current = This.Sender; string fullPropName = This.PropertyName; return(Reflection.TryGetValueForPropertyChain(out changeValue, current, fullPropName.Split('.'))); }
private static IObservedChange <object, object> ObservedChangeFor( Expression expression, IObservedChange <object, object> sourceChange) { if (sourceChange.Value == null) { return(new ObservedChange <object, object>(sourceChange.Value, expression)); } object value; // expression is always a simple expression Reflection.TryGetValueForPropertyChain(out value, sourceChange.Value, new[] { expression }); return(new ObservedChange <object, object>(sourceChange.Value, expression, value)); }
/// <summary> /// Returns the current value of a property given a notification that /// it has changed. /// </summary> /// <typeparam name="TSender">The sender.</typeparam> /// <typeparam name="TValue">The changed value.</typeparam> /// <param name="item"> /// The <see cref="IObservedChange{TSender, TValue}"/> instance to get the value of. /// </param> /// <returns> /// The current value of the property. /// </returns> public static TValue GetValue <TSender, TValue>(this IObservedChange <TSender, TValue> item) { if (item is null) { throw new ArgumentNullException(nameof(item)); } if (!item.TryGetValue(out var returnValue)) { throw new Exception($"One of the properties in the expression '{item.GetPropertyName()}' was null"); } return(returnValue); }
/// <summary> /// Attempts to return the current value of a property given a /// notification that it has changed. If any property in the /// property expression is null, false is returned. /// </summary> /// <typeparam name="TSender">The sender type.</typeparam> /// <typeparam name="TValue">The value type.</typeparam> /// <param name="item"> /// The <see cref="IObservedChange{TSender, TValue}"/> instance to get the value of. /// </param> /// <param name="changeValue"> /// The value of the property expression. /// </param> /// <returns> /// True if the entire expression was able to be followed, false otherwise. /// </returns> internal static bool TryGetValue <TSender, TValue>(this IObservedChange <TSender, TValue> item, out TValue changeValue) { if (Equals(item.Sender, null)) { throw new ArgumentNullException(nameof(item), "Sender of the item is null"); } if (!Equals(item.Value, default(TValue))) { changeValue = item.Value; return(true); } return(Reflection.TryGetValueForPropertyChain(out changeValue, item.Sender, item.Expression.GetExpressionChain())); }
private void NavigateToEntriesListView(IObservedChange<EntriesListViewModel, PwCommon> obj) { if (obj.Value is PwGroup) { _navigationService.UriFor<EntriesListViewModel>().WithParam(vm => vm.GroupId, obj.Value.UUID).Navigate(); } else if(obj.Value is PwEntry) { var entry = obj.Value as PwEntry; _navigationService .UriFor<AddOrEditEntryViewModel>() .WithParam(vm => vm.EntryUuid, entry.UUID) .WithParam(vm => vm.ParentGroupUuid, entry.ParentGroup.UUID) .Navigate(); } }
private void HandleStateChange(IObservedChange<CommandBase, CommandState> b) { CommandTraces.Add(new CommandTrace { DateTime = DateTime.Now, State = b.Value }); if (b.Value == CommandState.Successed) { SignalCommandFulfillment(); if (!ShouldExecuteForever) { CompleteCommand(); } else { CurrentState = CommandState.Executing; } } RegisterTimers(b.Value); }
/// <summary> /// WhenAny allows you to observe whenever one or more properties on an /// object have changed, providing an initial value when the Observable /// is set up, unlike ObservableForProperty(). Use this method in /// constructors to set up bindings between properties that also need an /// initial setup. /// </summary> public static IObservable <TRet> WhenAny <TSender, TRet, T1>(this TSender This, Expression <Func <TSender, T1> > property1, Func <IObservedChange <TSender, T1>, TRet> selector) { var slot1 = new ObservedChange <TSender, T1>() { Sender = This, PropertyName = String.Join(".", Reflection.ExpressionToPropertyNames(property1)), }; T1 slot1Value = default(T1); slot1.TryGetValue(out slot1Value); slot1.Value = slot1Value; IObservedChange <TSender, T1> islot1 = slot1; return(Observable.Create <TRet>(subject => { subject.OnNext(selector(islot1)); return Observable.Merge(This.ObservableForProperty(property1).Do(x => { lock (slot1) { islot1 = x.fillInValue(); } }).Select(x => selector(islot1))).Subscribe(subject); })); }
private static IObservable <IObservedChange <object, object> > NestedObservedChanges( Expression expression, IObservedChange <object, object> sourceChange, bool beforeChange) { // Make sure a change at a root node propagates events down var kicker = ObservedChangeFor(expression, sourceChange); // Handle null values in the chain if (sourceChange.Value == null) { return(Observable.Return(kicker)); } // Handle non null values in the chain return (NotifyForProperty(sourceChange.Value, expression, beforeChange) .Select(x => new ObservedChange <object, object>(x.Sender, expression, x.GetValue())) .StartWith(kicker)); }
/// <summary> /// WhenAny allows you to observe whenever one or more properties on an /// object have changed, providing an initial value when the Observable /// is set up, unlike ObservableForProperty(). Use this method in /// constructors to set up bindings between properties that also need an /// initial setup. /// </summary> public static IObservable <TRet> WhenAny <TSender, TRet, T1, T2, T3, T4>(this TSender This, Expression <Func <TSender, T1> > property1, Expression <Func <TSender, T2> > property2, Expression <Func <TSender, T3> > property3, Expression <Func <TSender, T4> > property4, Func <IObservedChange <TSender, T1>, IObservedChange <TSender, T2>, IObservedChange <TSender, T3>, IObservedChange <TSender, T4>, TRet> selector) { var slot1 = new ObservedChange <TSender, T1>() { Sender = This, PropertyName = String.Join(".", Reflection.ExpressionToPropertyNames(property1)), }; T1 slot1Value = default(T1); slot1.TryGetValue(out slot1Value); slot1.Value = slot1Value; IObservedChange <TSender, T1> islot1 = slot1; var slot2 = new ObservedChange <TSender, T2>() { Sender = This, PropertyName = String.Join(".", Reflection.ExpressionToPropertyNames(property2)), }; T2 slot2Value = default(T2); slot2.TryGetValue(out slot2Value); slot2.Value = slot2Value; IObservedChange <TSender, T2> islot2 = slot2; var slot3 = new ObservedChange <TSender, T3>() { Sender = This, PropertyName = String.Join(".", Reflection.ExpressionToPropertyNames(property3)), }; T3 slot3Value = default(T3); slot3.TryGetValue(out slot3Value); slot3.Value = slot3Value; IObservedChange <TSender, T3> islot3 = slot3; var slot4 = new ObservedChange <TSender, T4>() { Sender = This, PropertyName = String.Join(".", Reflection.ExpressionToPropertyNames(property4)), }; T4 slot4Value = default(T4); slot4.TryGetValue(out slot4Value); slot4.Value = slot4Value; IObservedChange <TSender, T4> islot4 = slot4; return(Observable.Create <TRet>(subject => { subject.OnNext(selector(islot1, islot2, islot3, islot4)); return Observable.Merge(This.ObservableForProperty(property1).Do(x => { lock (slot1) { islot1 = x.fillInValue(); } }).Select(x => selector(islot1, islot2, islot3, islot4)), This.ObservableForProperty(property2).Do(x => { lock (slot2) { islot2 = x.fillInValue(); } }).Select(x => selector(islot1, islot2, islot3, islot4)), This.ObservableForProperty(property3).Do(x => { lock (slot3) { islot3 = x.fillInValue(); } }).Select(x => selector(islot1, islot2, islot3, islot4)), This.ObservableForProperty(property4).Do(x => { lock (slot4) { islot4 = x.fillInValue(); } }).Select(x => selector(islot1, islot2, islot3, islot4))).Subscribe(subject); })); }
/// <summary> /// Given a fully filled-out IObservedChange object, SetValueToProperty /// will apply it to the specified object (i.e. it will ensure that /// target.property == This.GetValue() and "replay" the observed change /// onto another object) /// </summary> /// <param name="target">The target object to apply the change to.</param> /// <param name="property">The target property to apply the change to.</param> public static void SetValueToProperty <TSender, TValue, TTarget>( this IObservedChange <TSender, TValue> This, TTarget target, Expression <Func <TTarget, TValue> > property) { object current = target; string[] propNames = RxApp.expressionToPropertyNames(property); PropertyInfo pi; foreach (var propName in propNames.SkipLast(1)) { pi = RxApp.getPropertyInfoOrThrow(current.GetType(), propName); current = pi.GetValue(current, null); } pi = RxApp.getPropertyInfoForProperty(current.GetType(), propNames.Last()); pi.SetValue(current, This.GetValue(), null); }
public static bool TryGetAllValuesForPropertyChain(out IObservedChange <object, object>[] changeValues, object current, string[] propNames) { int currentIndex = 0; changeValues = new IObservedChange <object, object> [propNames.Length]; foreach (var propName in propNames.SkipLast(1)) { if (current == null) { changeValues[currentIndex] = null; return(false); } var box = new ObservedChange <object, object> { Sender = current, PropertyName = propName }; current = GetValueFetcherOrThrow(current.GetType(), propName)(current); box.Value = current; changeValues[currentIndex] = box; currentIndex++; } if (current == null) { changeValues[currentIndex] = null; return(false); } changeValues[currentIndex] = new ObservedChange <object, object> { Sender = current, PropertyName = propNames.Last(), Value = GetValueFetcherOrThrow(current.GetType(), propNames.Last())(current) }; return(true); }
/// <summary> /// Attempts to return the current value of a property given a /// notification that it has changed. If any property in the /// property expression is null, false is returned. /// </summary> /// <param name="changeValue">The value of the property expression.</param> /// <returns>True if the entire expression was able to be followed, false otherwise</returns> public static bool TryGetValue <TSender, TValue>(this IObservedChange <TSender, TValue> This, out TValue changeValue) { if (!Equals(This.Value, default(TValue))) { changeValue = This.Value; return(true); } object current = This.Sender; string[] propNames = null; lock (propStringToNameCache) { propNames = propStringToNameCache.Get(This.PropertyName); } PropertyInfo pi; foreach (var propName in propNames.SkipLast(1)) { if (current == null) { changeValue = default(TValue); return(false); } pi = RxApp.getPropertyInfoOrThrow(current.GetType(), propName); current = pi.GetValue(current, null); } if (current == null) { changeValue = default(TValue); return(false); } pi = RxApp.getPropertyInfoOrThrow(current.GetType(), propNames.Last()); changeValue = (TValue)pi.GetValue(current, null); return(true); }
private void NavigateToOpenDatabase(IObservedChange<DatabaseListViewModel, DatabaseItemViewModel> obj) { _cache.DatabaseName = obj.Value.DatabaseInfo.Info.DatabasePath; _navService.UriFor<OpenDatabaseViewModel>() .Navigate(); }
private void LiveLoginResultChanged(IObservedChange<SkydriveAccessViewModel, LiveLoginResult> obj) { OnLogin(obj.Value); }
private void SetupCanSave(IObservedChange<AddOrEditGroupViewModel, string> obj) { CanSave = !string.IsNullOrWhiteSpace(obj.Value); }
private void GetParentGroup(IObservedChange<AddOrEditGroupViewModel, string> obj) { ParentGroup = _databaseSource.PwDatabase.Tree.FindGroupByUuid(ParentGroupUuid); }
/// <summary> /// Returns the current value of a property given a notification that /// it has changed. /// </summary> /// <returns>The current value of the property</returns> public static string GetPropertyName <TSender, TValue>(this IObservedChange <TSender, TValue> This) { return(Reflection.ExpressionToPropertyNames(This.Expression)); }
private static bool CanExecuteLoginCommand(IObservedChange <MainViewModel, string> login, IObservedChange <MainViewModel, SecureString> password) { return(!string.IsNullOrEmpty(login.Value) && !string.IsNullOrEmpty(password.Value.ToInsecureString())); }
static IObservedChange <object, object> observedChangeFor(string propertyName, IObservedChange <object, object> sourceChange) { var p = new ObservedChange <object, object>() { Sender = sourceChange.Value, PropertyName = propertyName, }; if (sourceChange.Value == null) { return(p); } return(p.fillInValue()); }
static IObservable <IObservedChange <object, object> > nestedObservedChanges(string propertyName, IObservedChange <object, object> sourceChange, bool beforeChange) { // Make sure a change at a root node propogates events down var kicker = observedChangeFor(propertyName, sourceChange); // Handle null values in the chain if (sourceChange.Value == null) { return(Observable.Return(kicker)); } // Handle non null values in the chain return(notifyForProperty(sourceChange.Value, propertyName, beforeChange) .Select(x => x.fillInValue()) .StartWith(kicker)); }
internal static IObservedChange <TSender, TValue> fillInValue <TSender, TValue>(this IObservedChange <TSender, TValue> This) { // XXX: This is an internal method because I'm unsafely upcasting, // but in certain cases it's needed. var ret = (ObservedChange <TSender, TValue>)This; var val = default(TValue); This.TryGetValue(out val); ret.Value = val; return(ret); }
private void SkydriveItemSelected(IObservedChange<BrowseCloudFilesViewModel, ICloudItem> obj) { var value = obj.Value; if (value.IsFolder) { NavigateToBrowseFolders(value); } else { _dialogService.ShowDialogBox( "Download Confirmation", string.Format("Are you sure you want to download {0}?", value.Name), "yes", "no", async () => { await AttemptDownload(value); }, () => { SelectedSkyDriveItem = null; } ); } }
/// <summary> /// Returns the name of a property which has been changed. /// </summary> /// <typeparam name="TSender">The sender type.</typeparam> /// <typeparam name="TValue">The value type.</typeparam> /// <param name="item">The observed change.</param> /// <returns> /// The name of the property which has changed. /// </returns> public static string GetPropertyName <TSender, TValue>(this IObservedChange <TSender, TValue> item) => item is null ? throw new ArgumentNullException(nameof(item))
static IObservedChange <object, object> observedChangeFor(Expression expression, IObservedChange <object, object> sourceChange) { var propertyName = expression.GetMemberInfo().Name; if (sourceChange.Value == null) { return(new ObservedChange <object, object>(sourceChange.Value, expression));; } else { object value; // expression is always a simple expression Reflection.TryGetValueForPropertyChain(out value, sourceChange.Value, new[] { expression }); return(new ObservedChange <object, object>(sourceChange.Value, expression, value)); } }