housekeeping: fix analyzer warnings that have appeared in the fxcop (#2093)

This commit is contained in:
Glenn 2019-06-27 20:10:31 +10:00 коммит произвёл GitHub
Родитель 780a4bb0d7
Коммит 3c185b1039
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
100 изменённых файлов: 1010 добавлений и 366 удалений

Просмотреть файл

@ -26,6 +26,11 @@ namespace ReactiveUI.AndroidSupport
/// <param name="resolveMembers">The resolve members.</param>
public static void WireUpControls(this Fragment fragment, View inflatedView, ResolveStrategy resolveMembers = ResolveStrategy.Implicit)
{
if (fragment == null)
{
throw new ArgumentNullException(nameof(fragment));
}
var members = fragment.GetWireUpMembers(resolveMembers);
foreach (var member in members)

Просмотреть файл

@ -81,9 +81,23 @@ namespace ReactiveUI.AndroidSupport
}
/// <inheritdoc/>
public override void DestroyItem(ViewGroup container, int position, Object @object)
public override void DestroyItem(ViewGroup container, int position, Object item)
{
var view = (View)@object;
if (container == null)
{
throw new ArgumentNullException(nameof(container));
}
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
if (!(item is View view))
{
throw new ArgumentException("Item must be of type View", nameof(item));
}
container.RemoveView(view);
}

Просмотреть файл

@ -73,7 +73,17 @@ namespace ReactiveUI.AndroidSupport
/// <inheritdoc/>
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
((IViewFor)holder).ViewModel = GetViewModelByPosition(position);
if (holder == null)
{
throw new ArgumentNullException(nameof(holder));
}
if (!(holder is IViewFor viewForHolder))
{
throw new ArgumentException("Holder must be derived from IViewFor", nameof(holder));
}
viewForHolder.ViewModel = GetViewModelByPosition(position);
}
/// <inheritdoc/>

Просмотреть файл

@ -4,6 +4,7 @@
<TargetFrameworks>MonoAndroid81</TargetFrameworks>
<Description>ReactiveUI extensions for the Android Support Library</Description>
<PackageId>ReactiveUI.AndroidSupport</PackageId>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -89,17 +89,26 @@ namespace ReactiveUI.Blend
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
protected static void OnStateObservableChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var @this = (FollowObservableStateBehavior)sender;
if (@this._watcher != null)
if (e == null)
{
@this._watcher.Dispose();
@this._watcher = null;
throw new ArgumentNullException(nameof(e));
}
@this._watcher = ((IObservable<string>)e.NewValue).ObserveOn(RxApp.MainThreadScheduler).Subscribe(
if (!(sender is FollowObservableStateBehavior item))
{
throw new ArgumentException("Sender must be of type " + nameof(FollowObservableStateBehavior), nameof(sender));
}
if (item._watcher != null)
{
item._watcher.Dispose();
item._watcher = null;
}
item._watcher = ((IObservable<string>)e.NewValue).ObserveOn(RxApp.MainThreadScheduler).Subscribe(
x =>
{
var target = @this.TargetObject ?? @this.AssociatedObject;
var target = item.TargetObject ?? item.AssociatedObject;
#if NETFX_CORE
VisualStateManager.GoToState(target, x, true);
#else
@ -115,12 +124,12 @@ namespace ReactiveUI.Blend
},
ex =>
{
if (!@this.AutoResubscribeOnError)
if (!item.AutoResubscribeOnError)
{
return;
}
OnStateObservableChanged(@this, e);
OnStateObservableChanged(item, e);
});
}

Просмотреть файл

@ -47,7 +47,11 @@ namespace ReactiveUI.Blend
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
protected static void OnObservableChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
ObservableTrigger triggerItem = (ObservableTrigger)sender;
if (!(sender is ObservableTrigger triggerItem))
{
throw new ArgumentException("Sender must be of type " + nameof(ObservableTrigger), nameof(sender));
}
if (triggerItem._watcher != null)
{
triggerItem._watcher.Dispose();

Просмотреть файл

@ -6,6 +6,7 @@
<RootNamespace>ReactiveUI.Blend</RootNamespace>
<Description>Blend behaviors for ReactiveUI</Description>
<PackageId>ReactiveUI.Blend</PackageId>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -20,7 +20,7 @@ namespace ReactiveUI.Fody.Helpers
/// </summary>
/// <typeparam name="TObj">The type of the object.</typeparam>
/// <typeparam name="TRet">The type of the ret.</typeparam>
/// <param name="this">The this.</param>
/// <param name="item">The observable with the return value.</param>
/// <param name="source">The source.</param>
/// <param name="property">The property.</param>
/// <param name="initialValue">The initial value.</param>
@ -32,10 +32,20 @@ namespace ReactiveUI.Fody.Helpers
/// or
/// Backing field not found for " + propertyInfo.
/// </exception>
public static ObservableAsPropertyHelper<TRet> ToPropertyEx<TObj, TRet>(this IObservable<TRet> @this, TObj source, Expression<Func<TObj, TRet>> property, TRet initialValue = default(TRet), bool deferSubscription = false, IScheduler scheduler = null)
public static ObservableAsPropertyHelper<TRet> ToPropertyEx<TObj, TRet>(this IObservable<TRet> item, TObj source, Expression<Func<TObj, TRet>> property, TRet initialValue = default, bool deferSubscription = false, IScheduler scheduler = null)
where TObj : ReactiveObject
{
var result = @this.ToProperty(source, property, initialValue, deferSubscription, scheduler);
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
if (property == null)
{
throw new ArgumentNullException(nameof(property));
}
var result = item.ToProperty(source, property, initialValue, deferSubscription, scheduler);
// Now assign the field via reflection.
var propertyInfo = property.GetPropertyInfo();

Просмотреть файл

@ -11,6 +11,7 @@
<!-- Due to fody insisting on having .net 4 classes, we can't pack on non-windows -->
<IsPackable Condition=" '$(OS)' != 'Windows_NT' ">false</IsPackable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -13,7 +13,7 @@ namespace ReactiveUI.Fody.Helpers
}
public class static ObservableAsPropertyExtensions
{
public static ReactiveUI.ObservableAsPropertyHelper<TRet> ToPropertyEx<TObj, TRet>(this System.IObservable<TRet> @this, TObj source, System.Linq.Expressions.Expression<System.Func<TObj, TRet>> property, TRet initialValue = null, bool deferSubscription = False, System.Reactive.Concurrency.IScheduler scheduler = null)
public static ReactiveUI.ObservableAsPropertyHelper<TRet> ToPropertyEx<TObj, TRet>(this System.IObservable<TRet> item, TObj source, System.Linq.Expressions.Expression<System.Func<TObj, TRet>> property, TRet initialValue = null, bool deferSubscription = False, System.Reactive.Concurrency.IScheduler scheduler = null)
where TObj : ReactiveUI.ReactiveObject { }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Property | System.AttributeTargets.All)]

Просмотреть файл

@ -13,7 +13,7 @@ namespace ReactiveUI.Fody.Helpers
}
public class static ObservableAsPropertyExtensions
{
public static ReactiveUI.ObservableAsPropertyHelper<TRet> ToPropertyEx<TObj, TRet>(this System.IObservable<TRet> @this, TObj source, System.Linq.Expressions.Expression<System.Func<TObj, TRet>> property, TRet initialValue = null, bool deferSubscription = False, System.Reactive.Concurrency.IScheduler scheduler = null)
public static ReactiveUI.ObservableAsPropertyHelper<TRet> ToPropertyEx<TObj, TRet>(this System.IObservable<TRet> item, TObj source, System.Linq.Expressions.Expression<System.Func<TObj, TRet>> property, TRet initialValue = null, bool deferSubscription = False, System.Reactive.Concurrency.IScheduler scheduler = null)
where TObj : ReactiveUI.ReactiveObject { }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Property | System.AttributeTargets.All)]

Просмотреть файл

@ -4,6 +4,7 @@
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net461</TargetFrameworks>
<FodyTargetFramework>netstandard2.0</FodyTargetFramework>
<FodyTargetFramework Condition=" $(TargetFramework.StartsWith('net4')) ">$(TargetFramework)</FodyTargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -23,6 +23,16 @@ namespace ReactiveUI.Fody
/// <param name="il">The il.</param>
public static void Emit(this MethodBody body, Action<ILProcessor> il)
{
if (body == null)
{
throw new ArgumentNullException(nameof(body));
}
if (il == null)
{
throw new ArgumentNullException(nameof(il));
}
il(body.GetILProcessor());
}
@ -34,6 +44,11 @@ namespace ReactiveUI.Fody
/// <returns>A generic method with generic typed arguments.</returns>
public static GenericInstanceMethod MakeGenericMethod(this MethodReference method, params TypeReference[] genericArguments)
{
if (genericArguments == null)
{
throw new ArgumentNullException(nameof(genericArguments));
}
var result = new GenericInstanceMethod(method);
foreach (var argument in genericArguments)
{
@ -54,6 +69,16 @@ namespace ReactiveUI.Fody
/// </returns>
public static bool IsAssignableFrom(this TypeReference baseType, TypeReference type, Action<string> logger = null)
{
if (baseType == null)
{
throw new ArgumentNullException(nameof(baseType));
}
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
return baseType.Resolve().IsAssignableFrom(type.Resolve(), logger);
}
@ -107,6 +132,11 @@ namespace ReactiveUI.Fody
/// </returns>
public static bool IsDefined(this IMemberDefinition member, TypeReference attributeType)
{
if (member == null)
{
throw new ArgumentNullException(nameof(member));
}
return member.HasCustomAttributes && member.CustomAttributes.Any(x => x.AttributeType.FullName == attributeType.FullName);
}
@ -118,10 +148,17 @@ namespace ReactiveUI.Fody
/// <returns>The method bound to the generic type.</returns>
public static MethodReference Bind(this MethodReference method, GenericInstanceType genericType)
{
var reference = new MethodReference(method.Name, method.ReturnType, genericType);
reference.HasThis = method.HasThis;
reference.ExplicitThis = method.ExplicitThis;
reference.CallingConvention = method.CallingConvention;
if (method == null)
{
throw new ArgumentNullException(nameof(method));
}
var reference = new MethodReference(method.Name, method.ReturnType, genericType)
{
HasThis = method.HasThis,
ExplicitThis = method.ExplicitThis,
CallingConvention = method.CallingConvention
};
foreach (var parameter in method.Parameters)
{
@ -131,29 +168,6 @@ namespace ReactiveUI.Fody
return reference;
}
/*
public static MethodReference BindDefinition(this MethodReference method, TypeReference genericTypeDefinition)
{
if (!genericTypeDefinition.HasGenericParameters)
return method;
var genericDeclaration = new GenericInstanceType(genericTypeDefinition);
foreach (var parameter in genericTypeDefinition.GenericParameters)
{
genericDeclaration.GenericArguments.Add(parameter);
}
var reference = new MethodReference(method.Name, method.ReturnType, genericDeclaration);
reference.HasThis = method.HasThis;
reference.ExplicitThis = method.ExplicitThis;
reference.CallingConvention = method.CallingConvention;
foreach (var parameter in method.Parameters)
reference.Parameters.Add(new ParameterDefinition(parameter.ParameterType));
return reference;
}
*/
/// <summary>
/// Binds the generic type definition to a field.
/// </summary>
@ -162,6 +176,16 @@ namespace ReactiveUI.Fody
/// <returns>The field bound to the generic type.</returns>
public static FieldReference BindDefinition(this FieldReference field, TypeReference genericTypeDefinition)
{
if (field == null)
{
throw new ArgumentNullException(nameof(field));
}
if (genericTypeDefinition == null)
{
throw new ArgumentNullException(nameof(genericTypeDefinition));
}
if (!genericTypeDefinition.HasGenericParameters)
{
return field;
@ -185,6 +209,11 @@ namespace ReactiveUI.Fody
/// <returns>The assembly if found, null if not.</returns>
public static AssemblyNameReference FindAssembly(this ModuleDefinition currentModule, string assemblyName)
{
if (currentModule == null)
{
throw new ArgumentNullException(nameof(currentModule));
}
return currentModule.AssemblyReferences.SingleOrDefault(x => x.Name == assemblyName);
}
@ -199,6 +228,11 @@ namespace ReactiveUI.Fody
/// <returns>The type reference.</returns>
public static TypeReference FindType(this ModuleDefinition currentModule, string @namespace, string typeName, IMetadataScope scope = null, params string[] typeParameters)
{
if (typeParameters == null)
{
throw new ArgumentNullException(nameof(typeParameters));
}
var result = new TypeReference(@namespace, typeName, currentModule, scope);
foreach (var typeParameter in typeParameters)
{
@ -216,28 +250,17 @@ namespace ReactiveUI.Fody
/// <returns>A value indicating the result of the comparison.</returns>
public static bool CompareTo(this TypeReference type, TypeReference compareTo)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
if (compareTo == null)
{
throw new ArgumentNullException(nameof(compareTo));
}
return type.FullName == compareTo.FullName;
}
/*
public static IEnumerable<TypeDefinition> GetAllTypes(this ModuleDefinition module)
{
var stack = new Stack<TypeDefinition>();
foreach (var type in module.Types)
{
stack.Push(type);
}
while (stack.Any())
{
var current = stack.Pop();
yield return current;
foreach (var nestedType in current.NestedTypes)
{
stack.Push(nestedType);
}
}
}
*/
}
}

Просмотреть файл

@ -129,6 +129,16 @@ namespace ReactiveUI.Fody
/// <param name="type">The type.</param>
public void EmitDefaultValue(MethodBody methodBody, ILProcessor il, TypeReference type)
{
if (methodBody == null)
{
throw new ArgumentNullException(nameof(methodBody));
}
if (il == null)
{
throw new ArgumentNullException(nameof(il));
}
if (type.CompareTo(ModuleDefinition.TypeSystem.Boolean) || type.CompareTo(ModuleDefinition.TypeSystem.Byte) ||
type.CompareTo(ModuleDefinition.TypeSystem.Int16) || type.CompareTo(ModuleDefinition.TypeSystem.Int32))
{

Просмотреть файл

@ -4,6 +4,7 @@
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net461</TargetFrameworks>
<Description>Fody Weavers for ReactiveUI.Fody.</Description>
<IsPackable>False</IsPackable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -1,6 +1,7 @@
<Project Sdk="MSBuild.Sdk.Extras">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.DotMemoryUnit" Version="3.0.20171219.105559" />

Просмотреть файл

@ -4,6 +4,7 @@
<TargetFramework>netcoreapp2.2</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -4,6 +4,7 @@
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net461</TargetFrameworks>
<FodyTargetFramework>netstandard2.0</FodyTargetFramework>
<FodyTargetFramework Condition=" $(TargetFramework.StartsWith('net4')) ">$(TargetFramework)</FodyTargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -4,6 +4,7 @@
// See the LICENSE file in the project root for full license information.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace ReactiveUI.Testing.Tests
{
@ -30,6 +31,7 @@ namespace ReactiveUI.Testing.Tests
/// <summary>
/// Gets or sets the variables.
/// </summary>
[SuppressMessage("Design", "CA2227: Read only dictionary", Justification = "Used in mock.")]
public Dictionary<string, string> Variables { get; set; }
}
}

Просмотреть файл

@ -22,7 +22,14 @@ namespace ReactiveUI.Testing.Tests
/// </summary>
/// <param name="builder">The builder.</param>
/// <returns>The test fixture.</returns>
public static implicit operator TestFixture(TestFixtureBuilder builder) => builder.Build();
public static implicit operator TestFixture(TestFixtureBuilder builder) => ToTestFixture(builder);
/// <summary>
/// Performs conversion from <see cref="TestFixtureBuilder"/> to <see cref="TestFixture"/>.
/// </summary>
/// <param name="builder">The builder.</param>
/// <returns>The test fixture.</returns>
public static TestFixture ToTestFixture(TestFixtureBuilder builder) => builder.Build();
/// <summary>
/// Adds the count to the builder.

Просмотреть файл

@ -51,6 +51,11 @@ namespace ReactiveUI.Testing
IEnumerable<TField> values)
where TBuilder : IBuilder
{
if (field == null)
{
throw new System.ArgumentNullException(nameof(field));
}
if (values == null)
{
field = null;
@ -75,6 +80,11 @@ namespace ReactiveUI.Testing
public static TBuilder With<TBuilder, TField>(this TBuilder builder, ref List<TField> field, TField value)
where TBuilder : IBuilder
{
if (field == null)
{
throw new System.ArgumentNullException(nameof(field));
}
field.Add(value);
return builder;
}
@ -95,6 +105,11 @@ namespace ReactiveUI.Testing
KeyValuePair<TKey, TField> keyValuePair)
where TBuilder : IBuilder
{
if (dictionary == null)
{
throw new System.ArgumentNullException(nameof(dictionary));
}
dictionary.Add(keyValuePair.Key, keyValuePair.Value);
return builder;
}
@ -117,6 +132,11 @@ namespace ReactiveUI.Testing
TField value)
where TBuilder : IBuilder
{
if (dictionary == null)
{
throw new System.ArgumentNullException(nameof(dictionary));
}
dictionary.Add(key, value);
return builder;
}
@ -136,6 +156,11 @@ namespace ReactiveUI.Testing
ref Dictionary<TKey, TField> dictionary,
IDictionary<TKey, TField> keyValuePair)
{
if (dictionary == null)
{
throw new System.ArgumentNullException(nameof(dictionary));
}
dictionary = (Dictionary<TKey, TField>)keyValuePair;
return builder;
}

Просмотреть файл

@ -25,6 +25,11 @@ namespace ReactiveUI.Testing
/// <returns>The return value of the function.</returns>
public static TRet With<TRet>(this IMessageBus messageBus, Func<TRet> block)
{
if (block == null)
{
throw new ArgumentNullException(nameof(block));
}
using (messageBus.WithMessageBus())
{
return block();
@ -60,6 +65,11 @@ namespace ReactiveUI.Testing
/// <param name="block">The action to execute.</param>
public static void With(this IMessageBus messageBus, Action block)
{
if (block == null)
{
throw new ArgumentNullException(nameof(block));
}
using (messageBus.WithMessageBus())
{
block();

Просмотреть файл

@ -6,6 +6,7 @@
<RootNamespace>ReactiveUI.Testing</RootNamespace>
<Description>A library to aid in writing unit tests for ReactiveUI projects</Description>
<PackageId>ReactiveUI.Testing</PackageId>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -60,6 +60,11 @@ namespace ReactiveUI.Testing
public static TRet With<T, TRet>(this T sched, Func<T, TRet> block)
where T : IScheduler
{
if (block == null)
{
throw new ArgumentNullException(nameof(block));
}
TRet ret;
using (WithScheduler(sched))
{
@ -83,6 +88,11 @@ namespace ReactiveUI.Testing
public static async Task<TRet> WithAsync<T, TRet>(this T sched, Func<T, Task<TRet>> block)
where T : IScheduler
{
if (block == null)
{
throw new ArgumentNullException(nameof(block));
}
TRet ret;
using (WithScheduler(sched))
{
@ -137,6 +147,11 @@ namespace ReactiveUI.Testing
/// incremental, it sets the time.</param>
public static void AdvanceToMs(this TestScheduler sched, double milliseconds)
{
if (sched == null)
{
throw new ArgumentNullException(nameof(sched));
}
sched.AdvanceTo(sched.FromTimeSpan(TimeSpan.FromMilliseconds(milliseconds)));
}
@ -149,6 +164,11 @@ namespace ReactiveUI.Testing
/// by, in milliseconds.</param>
public static void AdvanceByMs(this TestScheduler sched, double milliseconds)
{
if (sched == null)
{
throw new ArgumentNullException(nameof(sched));
}
sched.AdvanceBy(sched.FromTimeSpan(TimeSpan.FromMilliseconds(milliseconds)));
}

Просмотреть файл

@ -395,9 +395,9 @@ namespace ReactiveUI
}
public class static ObservedChangedMixin
{
public static string GetPropertyName<TSender, TValue>(this ReactiveUI.IObservedChange<TSender, TValue> @this) { }
public static TValue GetValue<TSender, TValue>(this ReactiveUI.IObservedChange<TSender, TValue> @this) { }
public static System.IObservable<TValue> Value<TSender, TValue>(this System.IObservable<ReactiveUI.IObservedChange<TSender, TValue>> @this) { }
public static string GetPropertyName<TSender, TValue>(this ReactiveUI.IObservedChange<TSender, TValue> item) { }
public static TValue GetValue<TSender, TValue>(this ReactiveUI.IObservedChange<TSender, TValue> item) { }
public static System.IObservable<TValue> Value<TSender, TValue>(this System.IObservable<ReactiveUI.IObservedChange<TSender, TValue>> item) { }
}
public class static OrderedComparer
{
@ -504,11 +504,11 @@ namespace ReactiveUI
}
public class static ReactiveCommandMixins
{
public static System.IDisposable InvokeCommand<T>(this System.IObservable<T> @this, System.Windows.Input.ICommand command) { }
public static System.IDisposable InvokeCommand<T, TResult>(this System.IObservable<T> @this, ReactiveUI.ReactiveCommandBase<T, TResult> command) { }
public static System.IDisposable InvokeCommand<T, TTarget>(this System.IObservable<T> @this, TTarget target, System.Linq.Expressions.Expression<System.Func<TTarget, System.Windows.Input.ICommand>> commandProperty)
public static System.IDisposable InvokeCommand<T>(this System.IObservable<T> item, System.Windows.Input.ICommand command) { }
public static System.IDisposable InvokeCommand<T, TResult>(this System.IObservable<T> item, ReactiveUI.ReactiveCommandBase<T, TResult> command) { }
public static System.IDisposable InvokeCommand<T, TTarget>(this System.IObservable<T> item, TTarget target, System.Linq.Expressions.Expression<System.Func<TTarget, System.Windows.Input.ICommand>> commandProperty)
where TTarget : class { }
public static System.IDisposable InvokeCommand<T, TResult, TTarget>(this System.IObservable<T> @this, TTarget target, System.Linq.Expressions.Expression<System.Func<TTarget, ReactiveUI.ReactiveCommandBase<T, TResult>>> commandProperty)
public static System.IDisposable InvokeCommand<T, TResult, TTarget>(this System.IObservable<T> item, TTarget target, System.Linq.Expressions.Expression<System.Func<TTarget, ReactiveUI.ReactiveCommandBase<T, TResult>>> commandProperty)
where TTarget : class { }
}
public class ReactiveCommand<TParam, TResult> : ReactiveUI.ReactiveCommandBase<TParam, TResult>
@ -523,8 +523,8 @@ namespace ReactiveUI
}
public class static ReactiveNotifyPropertyChangedMixin
{
public static System.IObservable<ReactiveUI.IObservedChange<TSender, TValue>> ObservableForProperty<TSender, TValue>(this TSender @this, System.Linq.Expressions.Expression<System.Func<TSender, TValue>> property, bool beforeChange = False, bool skipInitial = True) { }
public static System.IObservable<TRet> ObservableForProperty<TSender, TValue, TRet>(this TSender @this, System.Linq.Expressions.Expression<System.Func<TSender, TValue>> property, System.Func<TValue, TRet> selector, bool beforeChange = False)
public static System.IObservable<ReactiveUI.IObservedChange<TSender, TValue>> ObservableForProperty<TSender, TValue>(this TSender item, System.Linq.Expressions.Expression<System.Func<TSender, TValue>> property, bool beforeChange = False, bool skipInitial = True) { }
public static System.IObservable<TRet> ObservableForProperty<TSender, TValue, TRet>(this TSender item, System.Linq.Expressions.Expression<System.Func<TSender, TValue>> property, System.Func<TValue, TRet> selector, bool beforeChange = False)
where TSender : class { }
public static System.IObservable<ReactiveUI.IObservedChange<TSender, TValue>> SubscribeToExpressionChain<TSender, TValue>(this TSender source, System.Linq.Expressions.Expression expression, bool beforeChange = False, bool skipInitial = True, bool suppressWarnings = False) { }
}
@ -562,7 +562,7 @@ namespace ReactiveUI
public static System.Func<object, object[], object> GetValueFetcherOrThrow(System.Reflection.MemberInfo member) { }
public static System.Action<object, object, object[]> GetValueSetterForProperty(System.Reflection.MemberInfo member) { }
public static System.Action<object, object, object[]> GetValueSetterOrThrow(System.Reflection.MemberInfo member) { }
public static bool IsStatic(this System.Reflection.PropertyInfo @this) { }
public static bool IsStatic(this System.Reflection.PropertyInfo item) { }
public static System.Type ReallyFindType(string type, bool throwOnFailure) { }
public static System.Linq.Expressions.Expression Rewrite(System.Linq.Expressions.Expression expression) { }
public static void ThrowIfMethodsNotOverloaded(string callingTypeName, object targetObject, params string[] methodsToCheck) { }
@ -577,9 +577,9 @@ namespace ReactiveUI
}
public class static RoutableViewModelMixin
{
public static System.IDisposable WhenNavigatedTo(this ReactiveUI.IRoutableViewModel @this, System.Func<System.IDisposable> onNavigatedTo) { }
public static System.IObservable<System.Reactive.Unit> WhenNavigatedToObservable(this ReactiveUI.IRoutableViewModel @this) { }
public static System.IObservable<System.Reactive.Unit> WhenNavigatingFromObservable(this ReactiveUI.IRoutableViewModel @this) { }
public static System.IDisposable WhenNavigatedTo(this ReactiveUI.IRoutableViewModel item, System.Func<System.IDisposable> onNavigatedTo) { }
public static System.IObservable<System.Reactive.Unit> WhenNavigatedToObservable(this ReactiveUI.IRoutableViewModel item) { }
public static System.IObservable<System.Reactive.Unit> WhenNavigatingFromObservable(this ReactiveUI.IRoutableViewModel item) { }
}
[System.Runtime.Serialization.DataContractAttribute()]
public class RoutingState : ReactiveUI.ReactiveObject
@ -603,9 +603,9 @@ namespace ReactiveUI
}
public class static RoutingStateMixins
{
public static T FindViewModelInStack<T>(this ReactiveUI.RoutingState @this)
public static T FindViewModelInStack<T>(this ReactiveUI.RoutingState item)
where T : ReactiveUI.IRoutableViewModel { }
public static ReactiveUI.IRoutableViewModel GetCurrentViewModel(this ReactiveUI.RoutingState @this) { }
public static ReactiveUI.IRoutableViewModel GetCurrentViewModel(this ReactiveUI.RoutingState item) { }
}
public class static RxApp
{
@ -641,10 +641,10 @@ namespace ReactiveUI
}
public class static SuspensionHostExtensions
{
public static T GetAppState<T>(this ReactiveUI.ISuspensionHost @this) { }
public static System.IObservable<T> ObserveAppState<T>(this ReactiveUI.ISuspensionHost @this)
public static T GetAppState<T>(this ReactiveUI.ISuspensionHost item) { }
public static System.IObservable<T> ObserveAppState<T>(this ReactiveUI.ISuspensionHost item)
where T : class { }
public static System.IDisposable SetupDefaultSuspendResume(this ReactiveUI.ISuspensionHost @this, ReactiveUI.ISuspensionDriver driver = null) { }
public static System.IDisposable SetupDefaultSuspendResume(this ReactiveUI.ISuspensionHost item, ReactiveUI.ISuspensionDriver driver = null) { }
}
public class UnhandledErrorException : System.Exception
{
@ -672,14 +672,14 @@ namespace ReactiveUI
}
public class static ViewForMixins
{
public static void WhenActivated(this ReactiveUI.ISupportsActivation @this, System.Func<System.Collections.Generic.IEnumerable<System.IDisposable>> block) { }
public static void WhenActivated(this ReactiveUI.ISupportsActivation @this, System.Action<System.Action<System.IDisposable>> block) { }
public static void WhenActivated(this ReactiveUI.ISupportsActivation @this, System.Action<System.Reactive.Disposables.CompositeDisposable> block) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable @this, System.Func<System.Collections.Generic.IEnumerable<System.IDisposable>> block) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable @this, System.Func<System.Collections.Generic.IEnumerable<System.IDisposable>> block, ReactiveUI.IViewFor view) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable @this, System.Action<System.Action<System.IDisposable>> block) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable @this, System.Action<System.Action<System.IDisposable>> block, ReactiveUI.IViewFor view) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable @this, System.Action<System.Reactive.Disposables.CompositeDisposable> block, ReactiveUI.IViewFor view = null) { }
public static void WhenActivated(this ReactiveUI.ISupportsActivation item, System.Func<System.Collections.Generic.IEnumerable<System.IDisposable>> block) { }
public static void WhenActivated(this ReactiveUI.ISupportsActivation item, System.Action<System.Action<System.IDisposable>> block) { }
public static void WhenActivated(this ReactiveUI.ISupportsActivation item, System.Action<System.Reactive.Disposables.CompositeDisposable> block) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable item, System.Func<System.Collections.Generic.IEnumerable<System.IDisposable>> block) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable item, System.Func<System.Collections.Generic.IEnumerable<System.IDisposable>> block, ReactiveUI.IViewFor view) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable item, System.Action<System.Action<System.IDisposable>> block) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable item, System.Action<System.Action<System.IDisposable>> block, ReactiveUI.IViewFor view) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable item, System.Action<System.Reactive.Disposables.CompositeDisposable> block, ReactiveUI.IViewFor view = null) { }
}
public class static ViewLocator
{

Просмотреть файл

@ -389,9 +389,9 @@ namespace ReactiveUI
}
public class static ObservedChangedMixin
{
public static string GetPropertyName<TSender, TValue>(this ReactiveUI.IObservedChange<TSender, TValue> @this) { }
public static TValue GetValue<TSender, TValue>(this ReactiveUI.IObservedChange<TSender, TValue> @this) { }
public static System.IObservable<TValue> Value<TSender, TValue>(this System.IObservable<ReactiveUI.IObservedChange<TSender, TValue>> @this) { }
public static string GetPropertyName<TSender, TValue>(this ReactiveUI.IObservedChange<TSender, TValue> item) { }
public static TValue GetValue<TSender, TValue>(this ReactiveUI.IObservedChange<TSender, TValue> item) { }
public static System.IObservable<TValue> Value<TSender, TValue>(this System.IObservable<ReactiveUI.IObservedChange<TSender, TValue>> item) { }
}
public class static OrderedComparer
{
@ -498,11 +498,11 @@ namespace ReactiveUI
}
public class static ReactiveCommandMixins
{
public static System.IDisposable InvokeCommand<T>(this System.IObservable<T> @this, System.Windows.Input.ICommand command) { }
public static System.IDisposable InvokeCommand<T, TResult>(this System.IObservable<T> @this, ReactiveUI.ReactiveCommandBase<T, TResult> command) { }
public static System.IDisposable InvokeCommand<T, TTarget>(this System.IObservable<T> @this, TTarget target, System.Linq.Expressions.Expression<System.Func<TTarget, System.Windows.Input.ICommand>> commandProperty)
public static System.IDisposable InvokeCommand<T>(this System.IObservable<T> item, System.Windows.Input.ICommand command) { }
public static System.IDisposable InvokeCommand<T, TResult>(this System.IObservable<T> item, ReactiveUI.ReactiveCommandBase<T, TResult> command) { }
public static System.IDisposable InvokeCommand<T, TTarget>(this System.IObservable<T> item, TTarget target, System.Linq.Expressions.Expression<System.Func<TTarget, System.Windows.Input.ICommand>> commandProperty)
where TTarget : class { }
public static System.IDisposable InvokeCommand<T, TResult, TTarget>(this System.IObservable<T> @this, TTarget target, System.Linq.Expressions.Expression<System.Func<TTarget, ReactiveUI.ReactiveCommandBase<T, TResult>>> commandProperty)
public static System.IDisposable InvokeCommand<T, TResult, TTarget>(this System.IObservable<T> item, TTarget target, System.Linq.Expressions.Expression<System.Func<TTarget, ReactiveUI.ReactiveCommandBase<T, TResult>>> commandProperty)
where TTarget : class { }
}
public class ReactiveCommand<TParam, TResult> : ReactiveUI.ReactiveCommandBase<TParam, TResult>
@ -517,8 +517,8 @@ namespace ReactiveUI
}
public class static ReactiveNotifyPropertyChangedMixin
{
public static System.IObservable<ReactiveUI.IObservedChange<TSender, TValue>> ObservableForProperty<TSender, TValue>(this TSender @this, System.Linq.Expressions.Expression<System.Func<TSender, TValue>> property, bool beforeChange = False, bool skipInitial = True) { }
public static System.IObservable<TRet> ObservableForProperty<TSender, TValue, TRet>(this TSender @this, System.Linq.Expressions.Expression<System.Func<TSender, TValue>> property, System.Func<TValue, TRet> selector, bool beforeChange = False)
public static System.IObservable<ReactiveUI.IObservedChange<TSender, TValue>> ObservableForProperty<TSender, TValue>(this TSender item, System.Linq.Expressions.Expression<System.Func<TSender, TValue>> property, bool beforeChange = False, bool skipInitial = True) { }
public static System.IObservable<TRet> ObservableForProperty<TSender, TValue, TRet>(this TSender item, System.Linq.Expressions.Expression<System.Func<TSender, TValue>> property, System.Func<TValue, TRet> selector, bool beforeChange = False)
where TSender : class { }
public static System.IObservable<ReactiveUI.IObservedChange<TSender, TValue>> SubscribeToExpressionChain<TSender, TValue>(this TSender source, System.Linq.Expressions.Expression expression, bool beforeChange = False, bool skipInitial = True, bool suppressWarnings = False) { }
}
@ -556,7 +556,7 @@ namespace ReactiveUI
public static System.Func<object, object[], object> GetValueFetcherOrThrow(System.Reflection.MemberInfo member) { }
public static System.Action<object, object, object[]> GetValueSetterForProperty(System.Reflection.MemberInfo member) { }
public static System.Action<object, object, object[]> GetValueSetterOrThrow(System.Reflection.MemberInfo member) { }
public static bool IsStatic(this System.Reflection.PropertyInfo @this) { }
public static bool IsStatic(this System.Reflection.PropertyInfo item) { }
public static System.Type ReallyFindType(string type, bool throwOnFailure) { }
public static System.Linq.Expressions.Expression Rewrite(System.Linq.Expressions.Expression expression) { }
public static void ThrowIfMethodsNotOverloaded(string callingTypeName, object targetObject, params string[] methodsToCheck) { }
@ -571,9 +571,9 @@ namespace ReactiveUI
}
public class static RoutableViewModelMixin
{
public static System.IDisposable WhenNavigatedTo(this ReactiveUI.IRoutableViewModel @this, System.Func<System.IDisposable> onNavigatedTo) { }
public static System.IObservable<System.Reactive.Unit> WhenNavigatedToObservable(this ReactiveUI.IRoutableViewModel @this) { }
public static System.IObservable<System.Reactive.Unit> WhenNavigatingFromObservable(this ReactiveUI.IRoutableViewModel @this) { }
public static System.IDisposable WhenNavigatedTo(this ReactiveUI.IRoutableViewModel item, System.Func<System.IDisposable> onNavigatedTo) { }
public static System.IObservable<System.Reactive.Unit> WhenNavigatedToObservable(this ReactiveUI.IRoutableViewModel item) { }
public static System.IObservable<System.Reactive.Unit> WhenNavigatingFromObservable(this ReactiveUI.IRoutableViewModel item) { }
}
[System.Runtime.Serialization.DataContractAttribute()]
public class RoutingState : ReactiveUI.ReactiveObject
@ -597,9 +597,9 @@ namespace ReactiveUI
}
public class static RoutingStateMixins
{
public static T FindViewModelInStack<T>(this ReactiveUI.RoutingState @this)
public static T FindViewModelInStack<T>(this ReactiveUI.RoutingState item)
where T : ReactiveUI.IRoutableViewModel { }
public static ReactiveUI.IRoutableViewModel GetCurrentViewModel(this ReactiveUI.RoutingState @this) { }
public static ReactiveUI.IRoutableViewModel GetCurrentViewModel(this ReactiveUI.RoutingState item) { }
}
public class static RxApp
{
@ -635,10 +635,10 @@ namespace ReactiveUI
}
public class static SuspensionHostExtensions
{
public static T GetAppState<T>(this ReactiveUI.ISuspensionHost @this) { }
public static System.IObservable<T> ObserveAppState<T>(this ReactiveUI.ISuspensionHost @this)
public static T GetAppState<T>(this ReactiveUI.ISuspensionHost item) { }
public static System.IObservable<T> ObserveAppState<T>(this ReactiveUI.ISuspensionHost item)
where T : class { }
public static System.IDisposable SetupDefaultSuspendResume(this ReactiveUI.ISuspensionHost @this, ReactiveUI.ISuspensionDriver driver = null) { }
public static System.IDisposable SetupDefaultSuspendResume(this ReactiveUI.ISuspensionHost item, ReactiveUI.ISuspensionDriver driver = null) { }
}
public class UnhandledErrorException : System.Exception
{
@ -666,14 +666,14 @@ namespace ReactiveUI
}
public class static ViewForMixins
{
public static void WhenActivated(this ReactiveUI.ISupportsActivation @this, System.Func<System.Collections.Generic.IEnumerable<System.IDisposable>> block) { }
public static void WhenActivated(this ReactiveUI.ISupportsActivation @this, System.Action<System.Action<System.IDisposable>> block) { }
public static void WhenActivated(this ReactiveUI.ISupportsActivation @this, System.Action<System.Reactive.Disposables.CompositeDisposable> block) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable @this, System.Func<System.Collections.Generic.IEnumerable<System.IDisposable>> block) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable @this, System.Func<System.Collections.Generic.IEnumerable<System.IDisposable>> block, ReactiveUI.IViewFor view) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable @this, System.Action<System.Action<System.IDisposable>> block) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable @this, System.Action<System.Action<System.IDisposable>> block, ReactiveUI.IViewFor view) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable @this, System.Action<System.Reactive.Disposables.CompositeDisposable> block, ReactiveUI.IViewFor view = null) { }
public static void WhenActivated(this ReactiveUI.ISupportsActivation item, System.Func<System.Collections.Generic.IEnumerable<System.IDisposable>> block) { }
public static void WhenActivated(this ReactiveUI.ISupportsActivation item, System.Action<System.Action<System.IDisposable>> block) { }
public static void WhenActivated(this ReactiveUI.ISupportsActivation item, System.Action<System.Reactive.Disposables.CompositeDisposable> block) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable item, System.Func<System.Collections.Generic.IEnumerable<System.IDisposable>> block) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable item, System.Func<System.Collections.Generic.IEnumerable<System.IDisposable>> block, ReactiveUI.IViewFor view) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable item, System.Action<System.Action<System.IDisposable>> block) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable item, System.Action<System.Action<System.IDisposable>> block, ReactiveUI.IViewFor view) { }
public static System.IDisposable WhenActivated(this ReactiveUI.IActivatable item, System.Action<System.Reactive.Disposables.CompositeDisposable> block, ReactiveUI.IViewFor view = null) { }
}
public class static ViewLocator
{

Просмотреть файл

@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net461</TargetFrameworks>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" $(TargetFramework.StartsWith('uap')) ">

Просмотреть файл

@ -18,6 +18,11 @@ namespace ReactiveUI.Uno
/// <inheritdoc/>
public void Register(Action<Func<object>, Type> registerFunction)
{
if (registerFunction == null)
{
throw new ArgumentNullException(nameof(registerFunction));
}
registerFunction(() => new PlatformOperations(), typeof(IPlatformOperations));
registerFunction(() => new ActivationForViewFetcher(), typeof(IActivationForViewFetcher));
registerFunction(() => new DependencyObjectObservableForProperty(), typeof(ICreatesObservableForProperty));

Просмотреть файл

@ -5,6 +5,7 @@
<Description>Uno Platform specific extensions for ReactiveUI</Description>
<DefineConstants>HAS_UNO</DefineConstants>
<NoWarn>$(NoWarn);SA1648;CA1816;CA1001;CS0108;CS0114;CS3021;CS1574;CA1303</NoWarn>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" $(TargetFramework.StartsWith('netstandard')) ">

Просмотреть файл

@ -32,7 +32,7 @@ namespace ReactiveUI.Uno
.SelectMany(x => FileIO.ReadTextAsync(x, UnicodeEncoding.Utf8).AsTask())
.SelectMany(x =>
{
var line = x.IndexOf('\n');
var line = x.IndexOf("\n", StringComparison.InvariantCulture);
var typeName = x.Substring(0, line - 1); // -1 for CR
var serializer = new DataContractSerializer(Type.GetType(typeName));
@ -45,6 +45,11 @@ namespace ReactiveUI.Uno
/// <inheritdoc/>
public IObservable<Unit> SaveState(object state)
{
if (state == null)
{
throw new ArgumentNullException(nameof(state));
}
try
{
var ms = new MemoryStream();

Просмотреть файл

@ -62,7 +62,7 @@ namespace ReactiveUI.Winforms
this.Log().Warn(
CultureInfo.InvariantCulture,
"Expected a view of type System.Windows.Forms.Control but it is {0}.\r\nYou need to implement your own IActivationForViewFetcher for {0}.",
view.GetType());
view?.GetType());
return Observable<bool>.Empty;
}

Просмотреть файл

@ -19,6 +19,11 @@ namespace ReactiveUI.Winforms
/// <inheritdoc/>
public bool ExecuteHook(object source, object target, Func<IObservedChange<object, object>[]> getCurrentViewModelProperties, Func<IObservedChange<object, object>[]> getCurrentViewProperties, BindingDirection direction)
{
if (getCurrentViewProperties == null)
{
throw new ArgumentNullException(nameof(getCurrentViewProperties));
}
var viewProperties = getCurrentViewProperties();
var lastViewProperty = viewProperties.LastOrDefault();

Просмотреть файл

@ -54,6 +54,11 @@ namespace ReactiveUI.Winforms
/// <inheritdoc/>
public IDisposable BindCommandToObject(ICommand command, object target, IObservable<object> commandParameter)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
const BindingFlags bf = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy;
var type = target.GetType();
@ -75,6 +80,16 @@ namespace ReactiveUI.Winforms
/// <inheritdoc/>
public IDisposable BindCommandToObject<TEventArgs>(ICommand command, object target, IObservable<object> commandParameter, string eventName)
{
if (command == null)
{
throw new ArgumentNullException(nameof(command));
}
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
var ret = new CompositeDisposable();
object latestParameter = null;

Просмотреть файл

@ -26,7 +26,7 @@ namespace ReactiveUI.Winforms
return 0;
}
if (fromType.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>) && x.GetGenericArguments().First().IsSubclassOf(typeof(Control))))
if (fromType?.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>) && x.GetGenericArguments().First().IsSubclassOf(typeof(Control))) ?? false)
{
return 10;
}
@ -37,6 +37,11 @@ namespace ReactiveUI.Winforms
/// <inheritdoc />
public object PerformSet(object toTarget, object newValue, object[] arguments)
{
if (toTarget == null)
{
throw new ArgumentNullException(nameof(toTarget));
}
IEnumerable<Control> newValueEnumerable = (IEnumerable<Control>)newValue;
Control.ControlCollection targetCollection = (Control.ControlCollection)toTarget;

Просмотреть файл

@ -8,6 +8,7 @@
<PackageId>ReactiveUI.WinForms</PackageId>
<UseWindowsForms>true</UseWindowsForms>
<ExtrasEnableWinFormsProjectSetup>true</ExtrasEnableWinFormsProjectSetup>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -19,6 +19,11 @@ namespace ReactiveUI.Winforms
/// <inheritdoc/>
public void Register(Action<Func<object>, Type> registerFunction)
{
if (registerFunction == null)
{
throw new ArgumentNullException(nameof(registerFunction));
}
registerFunction(() => new PlatformOperations(), typeof(IPlatformOperations));
registerFunction(() => new CreatesWinformsCommandBinding(), typeof(ICreatesCommandBinding));

Просмотреть файл

@ -25,7 +25,7 @@ namespace ReactiveUI.Winforms
return 0;
}
if (fromType.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>) && x.GetGenericArguments().First().IsSubclassOf(typeof(Control))))
if (fromType?.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>) && x.GetGenericArguments().First().IsSubclassOf(typeof(Control))) ?? false)
{
return 15;
}
@ -36,8 +36,17 @@ namespace ReactiveUI.Winforms
/// <inheritdoc />
public object PerformSet(object toTarget, object newValue, object[] arguments)
{
if (toTarget == null)
{
throw new ArgumentNullException(nameof(toTarget));
}
if (!(toTarget is TableLayoutControlCollection targetCollection))
{
throw new ArgumentException($"{nameof(toTarget)} must be of type {nameof(TableLayoutControlCollection)}");
}
IEnumerable<Control> newValueEnumerable = (IEnumerable<Control>)newValue;
TableLayoutControlCollection targetCollection = (TableLayoutControlCollection)toTarget;
targetCollection.Container.SuspendLayout();

Просмотреть файл

@ -45,6 +45,11 @@ namespace ReactiveUI.Winforms
/// <inheritdoc/>
public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, Expression expression, string propertyName, bool beforeChanged = false, bool suppressWarnings = false)
{
if (sender == null)
{
throw new ArgumentNullException(nameof(sender));
}
var ei = eventInfoCache.Get(Tuple.Create(sender.GetType(), propertyName));
return Observable.Create<IObservedChange<object, object>>(subj =>

Просмотреть файл

@ -36,6 +36,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged = false, bool suppressWarnings = false)
{
if (sender == null)
{
throw new ArgumentNullException(nameof(sender));
}
var type = sender.GetType();
var dpd = DependencyPropertyDescriptor.FromProperty(GetDependencyProperty(type, propertyName), type);

Просмотреть файл

@ -5,6 +5,7 @@
<PackageId>ReactiveUI.WPF</PackageId>
<UseWpf>true</UseWpf>
<ExtrasEnableWpfProjectSetup>true</ExtrasEnableWpfProjectSetup>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -16,6 +16,11 @@ namespace ReactiveUI.Wpf
/// <inheritdoc/>
public void Register(Action<Func<object>, Type> registerFunction)
{
if (registerFunction == null)
{
throw new ArgumentNullException(nameof(registerFunction));
}
registerFunction(() => new PlatformOperations(), typeof(IPlatformOperations));
registerFunction(() => new ActivationForViewFetcher(), typeof(IActivationForViewFetcher));

Просмотреть файл

@ -3,6 +3,7 @@
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<Description>Xamarin Forms specific extensions to ReactiveUI</Description>
<PackageId>ReactiveUI.XamForms</PackageId>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -21,6 +21,11 @@ namespace ReactiveUI.XamForms
/// <inheritdoc/>
public void Register(Action<Func<object>, Type> registerFunction)
{
if (registerFunction == null)
{
throw new ArgumentNullException(nameof(registerFunction));
}
registerFunction(() => new ActivationForViewFetcher(), typeof(IActivationForViewFetcher));
}
}

Просмотреть файл

@ -5,6 +5,7 @@
using System;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reflection;
@ -34,8 +35,14 @@ namespace ReactiveUI
/// <returns>An observable tracking whether the view is active.</returns>
public IObservable<bool> GetActivationForView(IActivatable view)
{
var ca = view as ICanActivate;
return ca.Activated.Select(_ => true).Merge(ca.Deactivated.Select(_ => false));
var canActivate = view as ICanActivate;
if (canActivate == null)
{
return Observable.Empty(false);
}
return canActivate.Activated.Select(_ => true).Merge(canActivate.Deactivated.Select(_ => false));
}
}
}

Просмотреть файл

@ -23,11 +23,11 @@ namespace ReactiveUI
(t, _) =>
Locator.Current
.GetServices<IActivationForViewFetcher>()
.Aggregate(Tuple.Create(0, default(IActivationForViewFetcher)), (acc, x) =>
.Aggregate((count: 0, viewFetcher: default(IActivationForViewFetcher)), (acc, x) =>
{
int score = x.GetAffinityForView(t);
return (score > acc.Item1) ? Tuple.Create(score, x) : acc;
}).Item2, RxApp.SmallCacheLimit);
return score > acc.count ? (score, x) : acc;
}).viewFetcher, RxApp.SmallCacheLimit);
static ViewForMixins()
{
@ -38,31 +38,41 @@ namespace ReactiveUI
/// WhenActivated allows you to register a Func to be called when a
/// ViewModel's View is Activated.
/// </summary>
/// <param name="this">Object that supports activation.</param>
/// <param name="item">Object that supports activation.</param>
/// <param name="block">
/// The method to be called when the corresponding
/// View is activated. It returns a list of Disposables that will be
/// cleaned up when the View is deactivated.
/// </param>
public static void WhenActivated(this ISupportsActivation @this, Func<IEnumerable<IDisposable>> block)
public static void WhenActivated(this ISupportsActivation item, Func<IEnumerable<IDisposable>> block)
{
@this.Activator.AddActivationBlock(block);
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
item.Activator.AddActivationBlock(block);
}
/// <summary>
/// WhenActivated allows you to register a Func to be called when a
/// ViewModel's View is Activated.
/// </summary>
/// <param name="this">Object that supports activation.</param>
/// <param name="item">Object that supports activation.</param>
/// <param name="block">
/// The method to be called when the corresponding
/// View is activated. The Action parameter (usually called 'd') allows
/// you to register Disposables to be cleaned up when the View is
/// deactivated (i.e. "d(someObservable.Subscribe());").
/// </param>
public static void WhenActivated(this ISupportsActivation @this, Action<Action<IDisposable>> block)
public static void WhenActivated(this ISupportsActivation item, Action<Action<IDisposable>> block)
{
@this.Activator.AddActivationBlock(() =>
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
item.Activator.AddActivationBlock(() =>
{
var ret = new List<IDisposable>();
block(ret.Add);
@ -74,15 +84,20 @@ namespace ReactiveUI
/// WhenActivated allows you to register a Func to be called when a
/// ViewModel's View is Activated.
/// </summary>
/// <param name="this">Object that supports activation.</param>
/// <param name="item">Object that supports activation.</param>
/// <param name="block">
/// The method to be called when the corresponding
/// View is activated. The Action parameter (usually called 'disposables') allows
/// you to collate all the disposables to be cleaned up during deactivation.
/// </param>
public static void WhenActivated(this ISupportsActivation @this, Action<CompositeDisposable> block)
public static void WhenActivated(this ISupportsActivation item, Action<CompositeDisposable> block)
{
@this.Activator.AddActivationBlock(() =>
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
item.Activator.AddActivationBlock(() =>
{
var d = new CompositeDisposable();
block(d);
@ -94,23 +109,28 @@ namespace ReactiveUI
/// WhenActivated allows you to register a Func to be called when a
/// View is Activated.
/// </summary>
/// <param name="this">Object that supports activation.</param>
/// <param name="item">Object that supports activation.</param>
/// <param name="block">
/// The method to be called when the corresponding
/// View is activated. It returns a list of Disposables that will be
/// cleaned up when the View is deactivated.
/// </param>
/// <returns>A Disposable that deactivates this registration.</returns>
public static IDisposable WhenActivated(this IActivatable @this, Func<IEnumerable<IDisposable>> block)
public static IDisposable WhenActivated(this IActivatable item, Func<IEnumerable<IDisposable>> block)
{
return @this.WhenActivated(block, null);
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
return item.WhenActivated(block, null);
}
/// <summary>
/// WhenActivated allows you to register a Func to be called when a
/// View is Activated.
/// </summary>
/// <param name="this">Object that supports activation.</param>
/// <param name="item">Object that supports activation.</param>
/// <param name="block">
/// The method to be called when the corresponding
/// View is activated. It returns a list of Disposables that will be
@ -122,19 +142,24 @@ namespace ReactiveUI
/// can be supplied here.
/// </param>
/// <returns>A Disposable that deactivates this registration.</returns>
public static IDisposable WhenActivated(this IActivatable @this, Func<IEnumerable<IDisposable>> block, IViewFor view)
public static IDisposable WhenActivated(this IActivatable item, Func<IEnumerable<IDisposable>> block, IViewFor view)
{
var activationFetcher = activationFetcherCache.Get(@this.GetType());
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
var activationFetcher = activationFetcherCache.Get(item.GetType());
if (activationFetcher == null)
{
const string msg = "Don't know how to detect when {0} is activated/deactivated, you may need to implement IActivationForViewFetcher";
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, msg, @this.GetType().FullName));
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, msg, item.GetType().FullName));
}
var activationEvents = activationFetcher.GetActivationForView(@this);
var activationEvents = activationFetcher.GetActivationForView(item);
var vmDisposable = Disposable.Empty;
if ((view ?? @this) is IViewFor v)
if ((view ?? item) is IViewFor v)
{
vmDisposable = HandleViewModelActivation(v, activationEvents);
}
@ -147,7 +172,7 @@ namespace ReactiveUI
/// WhenActivated allows you to register a Func to be called when a
/// View is Activated.
/// </summary>
/// <param name="this">Object that supports activation.</param>
/// <param name="item">Object that supports activation.</param>
/// <param name="block">
/// The method to be called when the corresponding
/// View is activated. The Action parameter (usually called 'd') allows
@ -155,16 +180,16 @@ namespace ReactiveUI
/// deactivated (i.e. "d(someObservable.Subscribe());").
/// </param>
/// <returns>A Disposable that deactivates this registration.</returns>
public static IDisposable WhenActivated(this IActivatable @this, Action<Action<IDisposable>> block)
public static IDisposable WhenActivated(this IActivatable item, Action<Action<IDisposable>> block)
{
return @this.WhenActivated(block, null);
return item.WhenActivated(block, null);
}
/// <summary>
/// WhenActivated allows you to register a Func to be called when a
/// View is Activated.
/// </summary>
/// <param name="this">Object that supports activation.</param>
/// <param name="item">Object that supports activation.</param>
/// <param name="block">
/// The method to be called when the corresponding
/// View is activated. The Action parameter (usually called 'd') allows
@ -177,9 +202,9 @@ namespace ReactiveUI
/// can be supplied here.
/// </param>
/// <returns>A Disposable that deactivates this registration.</returns>
public static IDisposable WhenActivated(this IActivatable @this, Action<Action<IDisposable>> block, IViewFor view)
public static IDisposable WhenActivated(this IActivatable item, Action<Action<IDisposable>> block, IViewFor view)
{
return @this.WhenActivated(
return item.WhenActivated(
() =>
{
var ret = new List<IDisposable>();
@ -192,7 +217,7 @@ namespace ReactiveUI
/// WhenActivated allows you to register a Func to be called when a
/// View is Activated.
/// </summary>
/// <param name="this">Object that supports activation.</param>
/// <param name="item">Object that supports activation.</param>
/// <param name="block">
/// The method to be called when the corresponding
/// View is activated. The Action parameter (usually called 'disposables') allows
@ -204,9 +229,9 @@ namespace ReactiveUI
/// can be supplied here.
/// </param>
/// <returns>A Disposable that deactivates this registration.</returns>
public static IDisposable WhenActivated(this IActivatable @this, Action<CompositeDisposable> block, IViewFor view = null)
public static IDisposable WhenActivated(this IActivatable item, Action<CompositeDisposable> block, IViewFor view = null)
{
return @this.WhenActivated(
return item.WhenActivated(
() =>
{
var d = new CompositeDisposable();

Просмотреть файл

@ -51,6 +51,16 @@ namespace ReactiveUI
where TView : class, IViewFor<TViewModel>
where TProp : ICommand
{
if (vmProperty == null)
{
throw new ArgumentNullException(nameof(vmProperty));
}
if (controlProperty == null)
{
throw new ArgumentNullException(nameof(controlProperty));
}
var vmExpression = Reflection.Rewrite(vmProperty.Body);
var controlExpression = Reflection.Rewrite(controlProperty.Body);
var source = Reflection.ViewModelWhenAnyValue(viewModel, view, vmExpression).Cast<TProp>();
@ -108,6 +118,16 @@ namespace ReactiveUI
where TView : class, IViewFor<TViewModel>
where TProp : ICommand
{
if (vmProperty == null)
{
throw new ArgumentNullException(nameof(vmProperty));
}
if (controlProperty == null)
{
throw new ArgumentNullException(nameof(controlProperty));
}
var vmExpression = Reflection.Rewrite(vmProperty.Body);
var controlExpression = Reflection.Rewrite(controlProperty.Body);
var source = Reflection.ViewModelWhenAnyValue(viewModel, view, vmExpression).Cast<TProp>();

Просмотреть файл

@ -45,6 +45,11 @@ namespace ReactiveUI
where TView : class, IViewFor<TViewModel>
where TProp : ICommand
{
if (withParameter == null)
{
throw new ArgumentNullException(nameof(withParameter));
}
var paramExpression = Reflection.Rewrite(withParameter.Body);
var param = Reflection.ViewModelWhenAnyValue(viewModel, view, paramExpression);

Просмотреть файл

@ -40,6 +40,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public IDisposable BindCommandToObject(ICommand command, object target, IObservable<object> commandParameter)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
var type = target.GetType();
var cmdPi = type.GetRuntimeProperty("Command");
var cmdParamPi = type.GetRuntimeProperty("CommandParameter");

Просмотреть файл

@ -51,6 +51,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public IDisposable BindCommandToObject(ICommand command, object target, IObservable<object> commandParameter)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
var type = target.GetType();
var eventInfo = defaultEventsToBind
.Select(x => new { EventInfo = type.GetRuntimeEvent(x.Item1), Args = x.Item2 })

Просмотреть файл

@ -123,6 +123,16 @@ namespace ReactiveUI
private static bool IsInstanceOfType(object from, Type targetType)
{
if (from == null)
{
throw new ArgumentNullException(nameof(from));
}
if (targetType == null)
{
throw new ArgumentNullException(nameof(targetType));
}
#if NETFX_CORE || PORTABLE
return targetType.GetTypeInfo().IsAssignableFrom(from.GetType().GetTypeInfo());
#else

Просмотреть файл

@ -23,7 +23,7 @@ namespace ReactiveUI
public bool TryConvert(object from, Type toType, object conversionHint, out object result)
{
// XXX: All Of The Localization
result = from.ToString();
result = from?.ToString();
return true;
}
}

Просмотреть файл

@ -188,6 +188,16 @@ namespace ReactiveUI
where TViewModel : class
where TView : class, IViewFor
{
if (vmProperty == null)
{
throw new ArgumentNullException(nameof(vmProperty));
}
if (viewProperty == null)
{
throw new ArgumentNullException(nameof(viewProperty));
}
if (vmToViewConverter == null)
{
throw new ArgumentNullException(nameof(vmToViewConverter));
@ -266,6 +276,16 @@ namespace ReactiveUI
where TViewModel : class
where TView : class, IViewFor
{
if (vmProperty == null)
{
throw new ArgumentNullException(nameof(vmProperty));
}
if (viewProperty == null)
{
throw new ArgumentNullException(nameof(viewProperty));
}
var vmExpression = Reflection.Rewrite(vmProperty.Body);
var viewExpression = Reflection.Rewrite(viewProperty.Body);
var viewType = viewExpression.Type;
@ -342,6 +362,16 @@ namespace ReactiveUI
where TViewModel : class
where TView : class, IViewFor
{
if (vmProperty == null)
{
throw new ArgumentNullException(nameof(vmProperty));
}
if (viewProperty == null)
{
throw new ArgumentNullException(nameof(viewProperty));
}
var vmExpression = Reflection.Rewrite(vmProperty.Body);
var viewExpression = Reflection.Rewrite(viewProperty.Body);
var ret = EvalBindingHooks(viewModel, view, vmExpression, viewExpression, BindingDirection.OneWay);
@ -394,6 +424,11 @@ namespace ReactiveUI
throw new ArgumentNullException(nameof(target));
}
if (propertyExpression == null)
{
throw new ArgumentNullException(nameof(propertyExpression));
}
var viewExpression = Reflection.Rewrite(propertyExpression.Body);
var ret = EvalBindingHooks(observedChange, target, null, viewExpression, BindingDirection.OneWay);
@ -538,6 +573,16 @@ namespace ReactiveUI
where TView : class, IViewFor
where TViewModel : class
{
if (vmProperty == null)
{
throw new ArgumentNullException(nameof(vmProperty));
}
if (viewProperty == null)
{
throw new ArgumentNullException(nameof(viewProperty));
}
var signalInitialUpdate = new Subject<bool>();
var vmExpression = Reflection.Rewrite(vmProperty.Body);
var viewExpression = Reflection.Rewrite(viewProperty.Body);

Просмотреть файл

@ -352,6 +352,11 @@ namespace ReactiveUI
/// <exception cref="Exception">If there is no event matching the name on the target type.</exception>
public static Type GetEventArgsTypeForEvent(Type type, string eventName)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
Type ti = type;
EventInfo ei = ti.GetRuntimeEvent(eventName);
if (ei == null)
@ -390,11 +395,16 @@ namespace ReactiveUI
/// <summary>
/// Determines if the specified property is static or not.
/// </summary>
/// <param name="this">The property information to check.</param>
/// <param name="item">The property information to check.</param>
/// <returns>If the property is static or not.</returns>
public static bool IsStatic(this PropertyInfo @this)
public static bool IsStatic(this PropertyInfo item)
{
return (@this.GetMethod ?? @this.SetMethod).IsStatic;
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
return (item.GetMethod ?? item.SetMethod).IsStatic;
}
[SuppressMessage("Microsoft.Performance", "CA1801", Justification = "TViewModel used to help generic calling.")]

Просмотреть файл

@ -26,6 +26,7 @@ using Splat;
#pragma warning disable SA1124 // Do not use regions -- not used for legacy
#pragma warning disable RCS1165 // Unconstrained null check -- not used for legacy
#pragma warning disable CA1001 // Undisposed type -- not used for legacy
#pragma warning disable CA1062 // null check
namespace ReactiveUI.Legacy
{

Просмотреть файл

@ -21,6 +21,11 @@ namespace ReactiveUI
/// <returns>If the change set is caused by the count being changed.</returns>
public static bool HasCountChanged(this IChangeSet changeSet)
{
if (changeSet == null)
{
throw new ArgumentNullException(nameof(changeSet));
}
return changeSet.Adds > 0 || changeSet.Removes > 0;
}

Просмотреть файл

@ -55,10 +55,19 @@ namespace ReactiveUI
/// <param name="assembly">The assembly to search using reflection for IViewFor classes.</param>
public static void RegisterViewsForViewModels(this IMutableDependencyResolver resolver, Assembly assembly)
{
if (resolver == null)
{
throw new ArgumentNullException(nameof(resolver));
}
if (assembly == null)
{
throw new ArgumentNullException(nameof(assembly));
}
// for each type that implements IViewFor
foreach (var ti in assembly.DefinedTypes
.Where(ti => ti.ImplementedInterfaces.Contains(typeof(IViewFor)))
.Where(ti => !ti.IsAbstract))
.Where(ti => ti.ImplementedInterfaces.Contains(typeof(IViewFor)) && !ti.IsAbstract))
{
// grab the first _implemented_ interface that also implements IViewFor, this should be the expected IViewFor<>
var ivf = ti.ImplementedInterfaces.FirstOrDefault(t => t.GetTypeInfo().ImplementedInterfaces.Contains(typeof(IViewFor)));

Просмотреть файл

@ -16,20 +16,25 @@ namespace System.Reactive.Disposables
/// <typeparam name="T">
/// The type of the disposable.
/// </typeparam>
/// <param name="this">
/// <param name="item">
/// The disposable we are going to want to be disposed by the CompositeDisposable.
/// </param>
/// <param name="compositeDisposable">
/// The <see cref="CompositeDisposable"/> to which <paramref name="this"/> will be added.
/// The <see cref="CompositeDisposable"/> to which <paramref name="item"/> will be added.
/// </param>
/// <returns>
/// The disposable.
/// </returns>
public static T DisposeWith<T>(this T @this, CompositeDisposable compositeDisposable)
public static T DisposeWith<T>(this T item, CompositeDisposable compositeDisposable)
where T : IDisposable
{
compositeDisposable.Add(@this);
return @this;
if (compositeDisposable == null)
{
throw new ArgumentNullException(nameof(compositeDisposable));
}
compositeDisposable.Add(item);
return item;
}
}
}
}

Просмотреть файл

@ -74,10 +74,15 @@ namespace ReactiveUI
/// going through the Conversion Expressions.
/// </summary>
/// <param name="expression">The expression.</param>
/// <returns>The member info from the epxression.</returns>
/// <returns>The member info from the expression.</returns>
public static MemberInfo GetMemberInfo(this Expression expression)
{
MemberInfo info = null;
if (expression == null)
{
throw new ArgumentNullException(nameof(expression));
}
MemberInfo info;
switch (expression.NodeType)
{
case ExpressionType.Index:
@ -103,6 +108,11 @@ namespace ReactiveUI
/// <returns>The parent expression.</returns>
public static Expression GetParent(this Expression expression)
{
if (expression == null)
{
throw new ArgumentNullException(nameof(expression));
}
switch (expression.NodeType)
{
case ExpressionType.Index:
@ -122,6 +132,11 @@ namespace ReactiveUI
/// <returns>An array of arguments.</returns>
public static object[] GetArgumentsArray(this Expression expression)
{
if (expression == null)
{
throw new ArgumentNullException(nameof(expression));
}
if (expression.NodeType == ExpressionType.Index)
{
return ((IndexExpression)expression).Arguments.Cast<ConstantExpression>().Select(c => c.Value).ToArray();

Просмотреть файл

@ -4,7 +4,6 @@
// See the LICENSE file in the project root for full license information.
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reactive.Linq;
@ -20,13 +19,18 @@ namespace ReactiveUI
/// </summary>
/// <typeparam name="TSender">The sender type.</typeparam>
/// <typeparam name="TValue">The value type.</typeparam>
/// <param name="this">The observed change.</param>
/// <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> @this)
public static string GetPropertyName<TSender, TValue>(this IObservedChange<TSender, TValue> item)
{
return Reflection.ExpressionToPropertyNames(@this.Expression);
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
return Reflection.ExpressionToPropertyNames(item.Expression);
}
/// <summary>
@ -35,21 +39,25 @@ namespace ReactiveUI
/// </summary>
/// <typeparam name="TSender">The sender.</typeparam>
/// <typeparam name="TValue">The changed value.</typeparam>
/// <param name="this">
/// <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> @this)
public static TValue GetValue<TSender, TValue>(this IObservedChange<TSender, TValue> item)
{
TValue ret;
if (!@this.TryGetValue(out ret))
if (item == null)
{
throw new Exception($"One of the properties in the expression '{@this.GetPropertyName()}' was null");
throw new ArgumentNullException(nameof(item));
}
return ret;
if (!item.TryGetValue(out var returnValue))
{
throw new Exception($"One of the properties in the expression '{item.GetPropertyName()}' was null");
}
return returnValue;
}
/// <summary>
@ -58,7 +66,7 @@ namespace ReactiveUI
/// </summary>
/// <typeparam name="TSender">The sender type.</typeparam>
/// <typeparam name="TValue">The value type.</typeparam>
/// <param name="this">
/// <param name="item">
/// The change notification stream to get the values of.
/// </param>
/// <returns>
@ -66,9 +74,9 @@ namespace ReactiveUI
/// the given change notification stream.
/// </returns>
public static IObservable<TValue> Value<TSender, TValue>(
this IObservable<IObservedChange<TSender, TValue>> @this)
this IObservable<IObservedChange<TSender, TValue>> item)
{
return @this.Select(GetValue);
return item.Select(GetValue);
}
/// <summary>
@ -78,7 +86,7 @@ namespace ReactiveUI
/// </summary>
/// <typeparam name="TSender">The sender type.</typeparam>
/// <typeparam name="TValue">The value type.</typeparam>
/// <param name="this">
/// <param name="item">
/// The <see cref="IObservedChange{TSender, TValue}"/> instance to get the value of.
/// </param>
/// <param name="changeValue">
@ -87,15 +95,15 @@ namespace ReactiveUI
/// <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)
internal static bool TryGetValue<TSender, TValue>(this IObservedChange<TSender, TValue> item, out TValue changeValue)
{
if (!Equals(@this.Value, default(TValue)))
if (!Equals(item.Value, default(TValue)))
{
changeValue = @this.Value;
changeValue = item.Value;
return true;
}
return Reflection.TryGetValueForPropertyChain(out changeValue, @this.Sender, @this.Expression.GetExpressionChain());
return Reflection.TryGetValueForPropertyChain(out changeValue, item.Sender, item.Expression.GetExpressionChain());
}
/// <summary>
@ -107,7 +115,7 @@ namespace ReactiveUI
/// <typeparam name="TSender">The sender type.</typeparam>
/// <typeparam name="TValue">The value type.</typeparam>
/// <typeparam name="TTarget">The target type.</typeparam>
/// <param name="this">
/// <param name="item">
/// The <see cref="IObservedChange{TSender, TValue}"/> instance to use as a
/// value to apply.
/// </param>
@ -118,11 +126,11 @@ namespace ReactiveUI
/// The target property to apply the change to.
/// </param>
internal static void SetValueToProperty<TSender, TValue, TTarget>(
this IObservedChange<TSender, TValue> @this,
this IObservedChange<TSender, TValue> item,
TTarget target,
Expression<Func<TTarget, TValue>> property)
{
Reflection.TrySetValueToPropertyChain(target, Reflection.Rewrite(property.Body).GetExpressionChain(), @this.GetValue());
Reflection.TrySetValueToPropertyChain(target, Reflection.Rewrite(property.Body).GetExpressionChain(), item.GetValue());
}
}
}

Просмотреть файл

@ -45,7 +45,7 @@ namespace ReactiveUI
/// </summary>
/// <typeparam name="TSender">The sender type.</typeparam>
/// <typeparam name="TValue">The value type.</typeparam>
/// <param name="this">The source object to observe properties of.</param>
/// <param name="item">The source object to observe properties of.</param>
/// <param name="property">An Expression representing the property (i.e.
/// 'x => x.SomeProperty.SomeOtherProperty'.</param>
/// <param name="beforeChange">If True, the Observable will notify
@ -55,14 +55,19 @@ namespace ReactiveUI
/// <returns>An Observable representing the property change
/// notifications for the given property.</returns>
public static IObservable<IObservedChange<TSender, TValue>> ObservableForProperty<TSender, TValue>(
this TSender @this,
this TSender item,
Expression<Func<TSender, TValue>> property,
bool beforeChange = false,
bool skipInitial = true)
{
if (@this == null)
if (item == null)
{
throw new ArgumentNullException(nameof(@this));
throw new ArgumentNullException(nameof(item));
}
if (property == null)
{
throw new ArgumentNullException(nameof(property));
}
/* x => x.Foo.Bar.Baz;
@ -81,7 +86,7 @@ namespace ReactiveUI
*/
return SubscribeToExpressionChain<TSender, TValue>(
@this,
item,
property.Body,
beforeChange,
skipInitial);
@ -96,7 +101,7 @@ namespace ReactiveUI
/// <typeparam name="TSender">The sender type.</typeparam>
/// <typeparam name="TValue">The value type.</typeparam>
/// <typeparam name="TRet">The return value type.</typeparam>
/// <param name="this">The source object to observe properties of.</param>
/// <param name="item">The source object to observe properties of.</param>
/// <param name="property">An Expression representing the property (i.e.
/// 'x => x.SomeProperty'.</param>
/// <param name="selector">A Select function that will be run on each
@ -106,14 +111,18 @@ namespace ReactiveUI
/// <returns>An Observable representing the property change
/// notifications for the given property.</returns>
public static IObservable<TRet> ObservableForProperty<TSender, TValue, TRet>(
this TSender @this,
this TSender item,
Expression<Func<TSender, TValue>> property,
Func<TValue, TRet> selector,
bool beforeChange = false)
where TSender : class
{
Contract.Requires(selector != null);
return @this.ObservableForProperty(property, beforeChange).Select(x => selector(x.Value));
if (selector == null)
{
throw new ArgumentNullException(nameof(property));
}
return item.ObservableForProperty(property, beforeChange).Select(x => selector(x.Value));
}
/// <summary>

Просмотреть файл

@ -28,6 +28,11 @@ namespace ReactiveUI
[SuppressMessage("Roslynator", "RCS1211", Justification = "Neater with else clause.")]
public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, Expression expression, string propertyName, bool beforeChanged, bool suppressWarnings = false)
{
if (expression == null)
{
throw new ArgumentNullException(nameof(expression));
}
var before = sender as INotifyPropertyChanging;
var after = sender as INotifyPropertyChanged;

Просмотреть файл

@ -27,6 +27,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, Expression expression, string propertyName, bool beforeChanged = false, bool suppressWarnings = false)
{
if (expression == null)
{
throw new ArgumentNullException(nameof(expression));
}
var iro = sender as IReactiveObject;
if (iro == null)
{

Просмотреть файл

@ -30,6 +30,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, Expression expression, string propertyName, bool beforeChanged = false, bool suppressWarnings = false)
{
if (sender == null)
{
throw new ArgumentNullException(nameof(sender));
}
var type = sender.GetType();
if (!hasWarned.ContainsKey((type, propertyName)) && !suppressWarnings)
{

Просмотреть файл

@ -54,6 +54,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, Expression expression, string propertyName, bool beforeChanged = false, bool suppressWarnings = false)
{
if (sender == null)
{
throw new ArgumentNullException(nameof(sender));
}
var type = sender.GetType();
var tableItem = dispatchTable.Keys.First(x => x.Item1.IsAssignableFrom(type) && x.Item2 == propertyName);

Просмотреть файл

@ -43,6 +43,11 @@ namespace ReactiveUI
/// <param name="hostApplication">The host application.</param>
public AutoSuspendHelper(Application hostApplication)
{
if (hostApplication == null)
{
throw new ArgumentNullException(nameof(hostApplication));
}
hostApplication.RegisterActivityLifecycleCallbacks(new ObservableLifecycle(this));
Observable.Merge(_onCreate, _onSaveInstanceState).Subscribe(x => LatestBundle = x);

Просмотреть файл

@ -53,6 +53,11 @@ namespace ReactiveUI
/// <param name="resolveMembers">The resolve members.</param>
public static void WireUpControls(this ILayoutViewHost layoutHost, ResolveStrategy resolveMembers = ResolveStrategy.Implicit)
{
if (layoutHost == null)
{
throw new ArgumentNullException(nameof(layoutHost));
}
var members = layoutHost.GetWireUpMembers(resolveMembers).ToList();
foreach (var member in members)
{
@ -76,6 +81,11 @@ namespace ReactiveUI
/// <param name="resolveMembers">The resolve members.</param>
public static void WireUpControls(this View view, ResolveStrategy resolveMembers = ResolveStrategy.Implicit)
{
if (view == null)
{
throw new ArgumentNullException(nameof(view));
}
var members = view.GetWireUpMembers(resolveMembers);
foreach (var member in members)
@ -105,6 +115,11 @@ namespace ReactiveUI
/// <param name="resolveMembers">The resolve members.</param>
public static void WireUpControls(this Fragment fragment, View inflatedView, ResolveStrategy resolveMembers = ResolveStrategy.Implicit)
{
if (fragment == null)
{
throw new ArgumentNullException(nameof(fragment));
}
var members = fragment.GetWireUpMembers(resolveMembers);
foreach (var member in members)
@ -132,6 +147,11 @@ namespace ReactiveUI
/// <param name="resolveMembers">The resolve members.</param>
public static void WireUpControls(this Activity activity, ResolveStrategy resolveMembers = ResolveStrategy.Implicit)
{
if (activity == null)
{
throw new ArgumentNullException(nameof(activity));
}
var members = activity.GetWireUpMembers(resolveMembers);
foreach (var member in members)
@ -179,10 +199,9 @@ namespace ReactiveUI
private static View GetCachedControl(string propertyName, object rootView, Func<View> fetchControlFromView)
{
View ret;
var ourViewCache = viewCache.GetOrCreateValue(rootView);
if (ourViewCache.TryGetValue(propertyName, out ret))
if (ourViewCache.TryGetValue(propertyName, out View ret))
{
return ret;
}

Просмотреть файл

@ -48,6 +48,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public IDisposable BindCommandToObject(ICommand command, object target, IObservable<object> commandParameter)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
var type = target.GetType();
var match = _config.Keys
@ -85,6 +90,11 @@ namespace ReactiveUI
/// <param name="enabledProperty">Enabled property name.</param>
protected static IDisposable ForEvent(ICommand command, object target, IObservable<object> commandParameter, string eventName, PropertyInfo enabledProperty)
{
if (command == null)
{
throw new ArgumentNullException(nameof(command));
}
commandParameter = commandParameter ?? Observable.Return(target);
object latestParam = null;

Просмотреть файл

@ -58,15 +58,15 @@ namespace ReactiveUI
}
_view = value;
_view.SetTag(ViewMixins.ViewHostTag, this.ToJavaObject());
_view?.SetTag(ViewMixins.ViewHostTag, this.ToJavaObject());
}
}
/// <summary>
/// Casts the LayoutViewHost to a View.
/// </summary>
/// <param name="this">The LayoutViewHost to cast.</param>
/// <param name="layoutViewHost">The LayoutViewHost to cast.</param>
[SuppressMessage("Usage", "CA2225: Provide a method named ToView", Justification = "A property is already provided.")]
public static implicit operator View(LayoutViewHost @this) => @this.View;
public static implicit operator View(LayoutViewHost layoutViewHost) => layoutViewHost?.View;
}
}

Просмотреть файл

@ -17,6 +17,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public void Register(Action<Func<object>, Type> registerFunction)
{
if (registerFunction == null)
{
throw new ArgumentNullException(nameof(registerFunction));
}
registerFunction(() => new PlatformOperations(), typeof(IPlatformOperations));
registerFunction(() => new ComponentModelTypeConverter(), typeof(IBindingTypeConverter));
registerFunction(() => new AndroidObservableForWidgets(), typeof(ICreatesObservableForProperty));

Просмотреть файл

@ -11,10 +11,12 @@ using Android.Views;
using Android.Widget;
using Splat;
#pragma warning disable CA1062 // null check -- legacy.
#pragma warning disable SA1600 // Elements should be documented
namespace ReactiveUI.Legacy
{
[Obsolete("ReactiveList is no longer supported. We suggest replacing it with DynamicData https://github.com/rolandpheasant/dynamicdata")]
#pragma warning disable SA1600 // Elements should be documented
public class ReactiveListAdapter<TViewModel> : BaseAdapter<TViewModel>, IEnableLogger
where TViewModel : class
{

Просмотреть файл

@ -21,35 +21,44 @@ namespace ReactiveUI
/// <summary>
/// Binds the command to target view control.
/// </summary>
/// <param name="this">The this.</param>
/// <param name="command">The command.</param>
/// <param name="control">The control.</param>
/// <returns>A disposable.</returns>
public static IDisposable BindToTarget(this ICommand @this, View control)
public static IDisposable BindToTarget(this ICommand command, View control)
{
if (command == null)
{
throw new ArgumentNullException(nameof(command));
}
if (control == null)
{
throw new ArgumentNullException(nameof(control));
}
var ev = new EventHandler((o, e) =>
{
if (!@this.CanExecute(null))
if (!command.CanExecute(null))
{
return;
}
@this.Execute(null);
command.Execute(null);
});
var cech = new EventHandler((o, e) =>
{
var canExecute = @this.CanExecute(null);
control.Enabled = canExecute;
control.Enabled = command.CanExecute(null);
});
@this.CanExecuteChanged += cech;
command.CanExecuteChanged += cech;
control.Click += ev;
control.Enabled = @this.CanExecute(null);
control.Enabled = command.CanExecute(null);
return Disposable.Create(() =>
{
@this.CanExecuteChanged -= cech;
command.CanExecuteChanged -= cech;
control.Click -= ev;
});
}

Просмотреть файл

@ -19,35 +19,29 @@ namespace ReactiveUI
/// Tag of the View.
/// </summary>
/// <typeparam name="T">The layout view host type.</typeparam>
/// <param name="this">The view.</param>
/// <param name="item">The view.</param>
/// <returns>The view host.</returns>
public static T GetViewHost<T>(this View @this)
public static T GetViewHost<T>(this View item)
where T : ILayoutViewHost
{
var tagData = @this.GetTag(ViewHostTag);
var tagData = item?.GetTag(ViewHostTag);
if (tagData != null)
{
return tagData.ToNetObject<T>();
}
return default(T);
return default;
}
/// <summary>
/// Gets the ViewHost associated with a given View by accessing the
/// Tag of the View.
/// </summary>
/// <param name="this">The view.</param>
/// <param name="item">The view.</param>
/// <returns>The view host.</returns>
public static ILayoutViewHost GetViewHost(this View @this)
public static ILayoutViewHost GetViewHost(this View item)
{
var tagData = @this.GetTag(ViewHostTag);
if (tagData != null)
{
return tagData.ToNetObject<ILayoutViewHost>();
}
return null;
return item?.GetTag(ViewHostTag)?.ToNetObject<ILayoutViewHost>();
}
}
}

Просмотреть файл

@ -27,13 +27,13 @@ namespace ReactiveUI
{
result = null;
if (val.GetType() == typeof(DateTime) && toType == typeof(NSDate))
if (val?.GetType() == typeof(DateTime) && toType == typeof(NSDate))
{
var dt = (DateTime)val;
result = (NSDate)dt;
return true;
}
else if (val.GetType() == typeof(NSDate) && toType == typeof(DateTime))
else if (val?.GetType() == typeof(NSDate) && toType == typeof(DateTime))
{
var dt = (NSDate)val;
result = (DateTime)dt;

Просмотреть файл

@ -59,6 +59,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, Expression expression, string propertyName, bool beforeChanged = false, bool suppressWarnings = false)
{
if (sender == null)
{
throw new ArgumentNullException(nameof(sender));
}
if (beforeChanged)
{
return Observable<IObservedChange<object, object>>.Never;

Просмотреть файл

@ -67,16 +67,27 @@ namespace ReactiveUI
/// <inheritdoc/>
public IDisposable BindCommandToObject(ICommand command, object target, IObservable<object> commandParameter)
{
if (command == null)
{
throw new ArgumentNullException(nameof(command));
}
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
commandParameter = commandParameter ?? Observable.Return(target);
object latestParam = null;
var ctlDelegate = new ControlDelegate(x =>
{
if (command.CanExecute(latestParam))
var ctlDelegate = new ControlDelegate(
x =>
{
command.Execute(latestParam);
}
}) { IsEnabled = command.CanExecute(latestParam) };
if (command.CanExecute(latestParam))
{
command.Execute(latestParam);
}
}) { IsEnabled = command.CanExecute(latestParam) };
var sel = new Selector("theAction:");

Просмотреть файл

@ -17,6 +17,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public void Register(Action<Func<object>, Type> registerFunction)
{
if (registerFunction == null)
{
throw new ArgumentNullException(nameof(registerFunction));
}
registerFunction(() => new PlatformOperations(), typeof(IPlatformOperations));
registerFunction(() => new ComponentModelTypeConverter(), typeof(IBindingTypeConverter));
registerFunction(() => new AppKitObservableForProperty(), typeof(ICreatesObservableForProperty));

Просмотреть файл

@ -17,6 +17,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public void Register(Action<Func<object>, Type> registerFunction)
{
if (registerFunction == null)
{
throw new ArgumentNullException(nameof(registerFunction));
}
registerFunction(() => new ComponentModelTypeConverter(), typeof(IBindingTypeConverter));
RxApp.TaskpoolScheduler = TaskPoolScheduler.Default;
RxApp.MainThreadScheduler = DefaultScheduler.Instance;

Просмотреть файл

@ -17,6 +17,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public void Register(Action<Func<object>, Type> registerFunction)
{
if (registerFunction == null)
{
throw new ArgumentNullException(nameof(registerFunction));
}
registerFunction(() => new PlatformOperations(), typeof(IPlatformOperations));
registerFunction(() => new ComponentModelTypeConverter(), typeof(IBindingTypeConverter));
RxApp.TaskpoolScheduler = TaskPoolScheduler.Default;

Просмотреть файл

@ -36,6 +36,11 @@ namespace ReactiveUI
/// <param name="app">The application.</param>
public AutoSuspendHelper(Application app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
Reflection.ThrowIfMethodsNotOverloaded("AutoSuspendHelper", app, "OnLaunched");
var launchNew = new[] { ApplicationExecutionState.ClosedByUser, ApplicationExecutionState.NotRunning, };

Просмотреть файл

@ -43,26 +43,21 @@ namespace ReactiveUI
/// <inheritdoc/>
public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged = false, bool suppressWarnings = false)
{
Contract.Requires(sender != null && sender is DependencyObject);
var type = sender.GetType();
if (sender == null)
{
throw new ArgumentNullException(nameof(sender));
}
var depSender = sender as DependencyObject;
if (depSender == null)
{
if (!suppressWarnings)
{
this.Log().Warn(
CultureInfo.InvariantCulture,
"Tried to bind DP on a non-DependencyObject. Binding as POCO object",
type.FullName,
propertyName);
}
var ret = new POCOObservableForProperty();
return ret.GetNotificationForProperty(sender, expression, propertyName, beforeChanged);
throw new ArgumentException("The sender must be a DependencyObject", nameof(sender));
}
if (beforeChanged == true)
var type = sender.GetType();
if (beforeChanged)
{
this.Log().Warn(
CultureInfo.InvariantCulture,

Просмотреть файл

@ -17,6 +17,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public void Register(Action<Func<object>, Type> registerFunction)
{
if (registerFunction == null)
{
throw new ArgumentNullException(nameof(registerFunction));
}
registerFunction(() => new PlatformOperations(), typeof(IPlatformOperations));
registerFunction(() => new ActivationForViewFetcher(), typeof(IActivationForViewFetcher));
registerFunction(() => new DependencyObjectObservableForProperty(), typeof(ICreatesObservableForProperty));

Просмотреть файл

@ -45,6 +45,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public IObservable<Unit> SaveState(object state)
{
if (state == null)
{
throw new ArgumentNullException(nameof(state));
}
try
{
var ms = new MemoryStream();

Просмотреть файл

@ -51,6 +51,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public IDisposable BindCommandToObject(ICommand command, object target, IObservable<object> commandParameter)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
var type = target.GetType();
var match = _config.Keys
@ -86,6 +91,11 @@ namespace ReactiveUI
/// <param name="enabledProperty">Enabled Property.</param>
protected static IDisposable ForEvent(ICommand command, object target, IObservable<object> commandParameter, string eventName, PropertyInfo enabledProperty)
{
if (command == null)
{
throw new ArgumentNullException(nameof(command));
}
commandParameter = commandParameter ?? Observable.Return(target);
object latestParam = null;
@ -126,6 +136,11 @@ namespace ReactiveUI
/// <returns>Returns a disposable.</returns>
protected static IDisposable ForTargetAction(ICommand command, object target, IObservable<object> commandParameter, PropertyInfo enabledProperty)
{
if (command == null)
{
throw new ArgumentNullException(nameof(command));
}
commandParameter = commandParameter ?? Observable.Return(target);
object latestParam = null;

Просмотреть файл

@ -17,6 +17,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public void Register(Action<Func<object>, Type> registerFunction)
{
if (registerFunction == null)
{
throw new ArgumentNullException(nameof(registerFunction));
}
registerFunction(() => new PlatformOperations(), typeof(IPlatformOperations));
registerFunction(() => new ComponentModelTypeConverter(), typeof(IBindingTypeConverter));
registerFunction(() => new UIKitObservableForProperty(), typeof(ICreatesObservableForProperty));

Просмотреть файл

@ -122,6 +122,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
{
if (indexPath == null)
{
throw new ArgumentNullException(nameof(indexPath));
}
return _commonSource.GetCell(indexPath);
}
@ -140,6 +145,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public override void ItemSelected(UICollectionView collectionView, NSIndexPath indexPath)
{
if (indexPath == null)
{
throw new ArgumentNullException(nameof(indexPath));
}
_elementSelected.OnNext(_commonSource.ItemAt(indexPath));
}
@ -150,6 +160,11 @@ namespace ReactiveUI
/// <returns>The object at the specified index.</returns>
public object ItemAt(NSIndexPath indexPath)
{
if (indexPath == null)
{
throw new ArgumentNullException(nameof(indexPath));
}
return _commonSource.ItemAt(indexPath);
}

Просмотреть файл

@ -103,6 +103,11 @@ namespace ReactiveUI
Func<ReactiveCollectionViewSource<TSource>, IDisposable> initSource = null)
where TCell : UICollectionViewCell
{
if (collectionView == null)
{
throw new ArgumentNullException(nameof(collectionView));
}
var type = typeof(TCell);
var cellKey = new NSString(type.ToString());
collectionView.RegisterClassForCell(type, new NSString(cellKey));

Просмотреть файл

@ -7,10 +7,6 @@ using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using Foundation;
using ReactiveUI.Legacy;
@ -175,6 +171,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
if (indexPath == null)
{
throw new ArgumentNullException(nameof(indexPath));
}
return _commonSource.GetCell(indexPath);
}
@ -206,11 +207,24 @@ namespace ReactiveUI
/// <inheritdoc/>
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
if (indexPath == null)
{
throw new ArgumentNullException(nameof(indexPath));
}
_elementSelected.OnNext(_commonSource.ItemAt(indexPath));
}
/// <inheritdoc/>
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath) => _commonSource.SectionInfo[indexPath.Section].SizeHint;
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
if (indexPath == null)
{
throw new ArgumentNullException(nameof(indexPath));
}
return _commonSource.SectionInfo[indexPath.Section].SizeHint;
}
/// <inheritdoc/>
public override nfloat GetHeightForHeader(UITableView tableView, nint section)
@ -239,35 +253,35 @@ namespace ReactiveUI
}
var footer = _commonSource.SectionInfo[(int)section].Footer;
return footer == null || footer.View == null ? -1 : footer.Height;
return footer?.View == null ? -1 : footer.Height;
}
/// <inheritdoc/>
public override string TitleForHeader(UITableView tableView, nint section)
{
var header = _commonSource.SectionInfo[(int)section].Header;
return header == null || header.Title == null ? null : header.Title;
return header?.Title;
}
/// <inheritdoc/>
public override string TitleForFooter(UITableView tableView, nint section)
{
var footer = _commonSource.SectionInfo[(int)section].Footer;
return footer == null || footer.Title == null ? null : footer.Title;
return footer?.Title;
}
/// <inheritdoc/>
public override UIView GetViewForHeader(UITableView tableView, nint section)
{
var header = _commonSource.SectionInfo[(int)section].Header;
return header == null || header.View == null ? null : header.View.Invoke();
return header?.View?.Invoke();
}
/// <inheritdoc/>
public override UIView GetViewForFooter(UITableView tableView, nint section)
{
var footer = _commonSource.SectionInfo[(int)section].Footer;
return footer == null || footer.View == null ? null : footer.View.Invoke();
return footer?.View?.Invoke();
}
/// <summary>
@ -275,7 +289,15 @@ namespace ReactiveUI
/// </summary>
/// <param name="indexPath">The index path.</param>
/// <returns>The item.</returns>
public object ItemAt(NSIndexPath indexPath) => _commonSource.ItemAt(indexPath);
public object ItemAt(NSIndexPath indexPath)
{
if (indexPath == null)
{
throw new ArgumentNullException(nameof(indexPath));
}
return _commonSource.ItemAt(indexPath);
}
/// <summary>
/// When this method is called, an object will not fire change

Просмотреть файл

@ -109,6 +109,11 @@ namespace ReactiveUI
Func<ReactiveTableViewSource<TSource>, IDisposable> initSource = null)
where TCell : UITableViewCell
{
if (tableView == null)
{
throw new ArgumentNullException(nameof(tableView));
}
var type = typeof(TCell);
var cellKey = new NSString(type.ToString());
tableView.RegisterClassForCellReuse(type, new NSString(cellKey));

Просмотреть файл

@ -133,6 +133,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public override void PushViewController(NSViewController viewController, bool animated)
{
if (viewController == null)
{
throw new ArgumentNullException(nameof(viewController));
}
base.PushViewController(viewController, animated);
if (!_routerInstigated)

Просмотреть файл

@ -18,37 +18,46 @@ namespace ReactiveUI
/// <summary>
/// Binds the <see cref="ICommand"/> to target <see cref="UIControl"/>.
/// </summary>
/// <param name="this">The this.</param>
/// <param name="item">The command to bind to.</param>
/// <param name="control">The control.</param>
/// <param name="events">The events.</param>
/// <returns>A disposable.</returns>
public static IDisposable BindToTarget(this ICommand @this, UIControl control, UIControlEvent events)
public static IDisposable BindToTarget(this ICommand item, UIControl control, UIControlEvent events)
{
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
if (control == null)
{
throw new ArgumentNullException(nameof(control));
}
var ev = new EventHandler((o, e) =>
{
if (!@this.CanExecute(null))
if (!item.CanExecute(null))
{
return;
}
@this.Execute(null);
item.Execute(null);
});
var cech = new EventHandler((o, e) =>
{
var canExecute = @this.CanExecute(null);
control.Enabled = canExecute;
control.Enabled = item.CanExecute(null);
});
@this.CanExecuteChanged += cech;
item.CanExecuteChanged += cech;
control.AddTarget(ev, events);
control.Enabled = @this.CanExecute(null);
control.Enabled = item.CanExecute(null);
return Disposable.Create(() =>
{
control.RemoveTarget(ev, events);
@this.CanExecuteChanged -= cech;
item.CanExecuteChanged -= cech;
});
}
}

Просмотреть файл

@ -56,15 +56,15 @@ namespace ReactiveUI
/// <inheritdoc/>
public bool ExecuteHook(object source, object target, Func<IObservedChange<object, object>[]> getCurrentViewModelProperties, Func<IObservedChange<object, object>[]> getCurrentViewProperties, BindingDirection direction)
{
var viewProperties = getCurrentViewProperties();
var lastViewProperty = viewProperties.LastOrDefault();
if (lastViewProperty == null)
if (getCurrentViewProperties == null)
{
return true;
throw new ArgumentNullException(nameof(getCurrentViewProperties));
}
var itemsControl = lastViewProperty.Sender as ItemsControl;
if (itemsControl == null)
var viewProperties = getCurrentViewProperties();
var lastViewProperty = viewProperties.LastOrDefault();
if (!(lastViewProperty?.Sender is ItemsControl itemsControl))
{
return true;
}

Просмотреть файл

@ -22,18 +22,18 @@ namespace ReactiveUI
/// the command can be executed, Execute() will be called).
/// </summary>
/// <typeparam name="T">The type.</typeparam>
/// <param name="this">The source observable to pipe into the command.</param>
/// <param name="item">The source observable to pipe into the command.</param>
/// <param name="command">The command to be executed.</param>
/// <returns>An object that when disposes, disconnects the Observable
/// from the command.</returns>
public static IDisposable InvokeCommand<T>(this IObservable<T> @this, ICommand command)
public static IDisposable InvokeCommand<T>(this IObservable<T> item, ICommand command)
{
var canExecuteChanged = Observable
.FromEventPattern(h => command.CanExecuteChanged += h, h => command.CanExecuteChanged -= h)
.Select(_ => Unit.Default)
.StartWith(Unit.Default);
return WithLatestFromFixed(@this, canExecuteChanged, (value, _) => InvokeCommandInfo.From(command, command.CanExecute(value), value))
return WithLatestFromFixed(item, canExecuteChanged, (value, _) => InvokeCommandInfo.From(command, command.CanExecute(value), value))
.Where(ii => ii.CanExecute)
.Do(ii => command.Execute(ii.Value))
.Subscribe();
@ -46,13 +46,18 @@ namespace ReactiveUI
/// </summary>
/// <typeparam name="T">The type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam>
/// <param name="this">The source observable to pipe into the command.</param>
/// <param name="item">The source observable to pipe into the command.</param>
/// <param name="command">The command to be executed.</param>
/// <returns>An object that when disposes, disconnects the Observable
/// from the command.</returns>
public static IDisposable InvokeCommand<T, TResult>(this IObservable<T> @this, ReactiveCommandBase<T, TResult> command)
public static IDisposable InvokeCommand<T, TResult>(this IObservable<T> item, ReactiveCommandBase<T, TResult> command)
{
return WithLatestFromFixed(@this, command.CanExecute, (value, canExecute) => InvokeCommandInfo.From(command, canExecute, value))
if (command == null)
{
throw new ArgumentNullException(nameof(command));
}
return WithLatestFromFixed(item, command.CanExecute, (value, canExecute) => InvokeCommandInfo.From(command, canExecute, value))
.Where(ii => ii.CanExecute)
.SelectMany(ii => command.Execute(ii.Value).Catch(Observable<TResult>.Empty))
.Subscribe();
@ -65,12 +70,12 @@ namespace ReactiveUI
/// </summary>
/// <typeparam name="T">The type.</typeparam>
/// <typeparam name="TTarget">The target type.</typeparam>
/// <param name="this">The source observable to pipe into the command.</param>
/// <param name="item">The source observable to pipe into the command.</param>
/// <param name="target">The root object which has the Command.</param>
/// <param name="commandProperty">The expression to reference the Command.</param>
/// <returns>An object that when disposes, disconnects the Observable
/// from the command.</returns>
public static IDisposable InvokeCommand<T, TTarget>(this IObservable<T> @this, TTarget target, Expression<Func<TTarget, ICommand>> commandProperty)
public static IDisposable InvokeCommand<T, TTarget>(this IObservable<T> item, TTarget target, Expression<Func<TTarget, ICommand>> commandProperty)
where TTarget : class
{
var command = target.WhenAnyValue(commandProperty);
@ -81,7 +86,7 @@ namespace ReactiveUI
.StartWith(c))
.Switch();
return WithLatestFromFixed(@this, commandCanExecuteChanged, (value, cmd) => InvokeCommandInfo.From(cmd, cmd.CanExecute(value), value))
return WithLatestFromFixed(item, commandCanExecuteChanged, (value, cmd) => InvokeCommandInfo.From(cmd, cmd.CanExecute(value), value))
.Where(ii => ii.CanExecute)
.Do(ii => ii.Command.Execute(ii.Value))
.Subscribe();
@ -95,12 +100,12 @@ namespace ReactiveUI
/// <typeparam name="T">The type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam>
/// <typeparam name="TTarget">The target type.</typeparam>
/// <param name="this">The source observable to pipe into the command.</param>
/// <param name="item">The source observable to pipe into the command.</param>
/// <param name="target">The root object which has the Command.</param>
/// <param name="commandProperty">The expression to reference the Command.</param>
/// <returns>An object that when disposes, disconnects the Observable
/// from the command.</returns>
public static IDisposable InvokeCommand<T, TResult, TTarget>(this IObservable<T> @this, TTarget target, Expression<Func<TTarget, ReactiveCommandBase<T, TResult>>> commandProperty)
public static IDisposable InvokeCommand<T, TResult, TTarget>(this IObservable<T> item, TTarget target, Expression<Func<TTarget, ReactiveCommandBase<T, TResult>>> commandProperty)
where TTarget : class
{
var command = target.WhenAnyValue(commandProperty);
@ -110,7 +115,7 @@ namespace ReactiveUI
.Select(canExecute => InvokeCommandInfo.From(cmd, canExecute, default(T))))
.Switch();
return WithLatestFromFixed(@this, invocationInfo, (value, ii) => ii.WithValue(value))
return WithLatestFromFixed(item, invocationInfo, (value, ii) => ii.WithValue(value))
.Where(ii => ii.CanExecute)
.SelectMany(ii => ii.Command.Execute(ii.Value).Catch(Observable<TResult>.Empty))
.Subscribe();
@ -118,10 +123,10 @@ namespace ReactiveUI
// See https://github.com/Reactive-Extensions/Rx.NET/issues/444
private static IObservable<TResult> WithLatestFromFixed<TLeft, TRight, TResult>(
IObservable<TLeft> @this,
IObservable<TLeft> item,
IObservable<TRight> other,
Func<TLeft, TRight, TResult> resultSelector) =>
@this
item
.Publish(
os =>
other
@ -133,30 +138,21 @@ namespace ReactiveUI
private struct InvokeCommandInfo<TCommand, TValue>
{
private readonly TCommand _command;
private readonly bool _canExecute;
private readonly TValue _value;
public InvokeCommandInfo(TCommand command, bool canExecute)
: this(command, canExecute, default(TValue))
public InvokeCommandInfo(TCommand command, bool canExecute, TValue value = default)
{
Command = command;
CanExecute = canExecute;
Value = value;
}
public InvokeCommandInfo(TCommand command, bool canExecute, TValue value)
{
_command = command;
_canExecute = canExecute;
_value = value;
}
public TCommand Command { get; }
public TCommand Command => _command;
public bool CanExecute { get; }
public bool CanExecute => _canExecute;
public TValue Value => _value;
public TValue Value { get; }
public InvokeCommandInfo<TCommand, TValue> WithValue(TValue value) =>
new InvokeCommandInfo<TCommand, TValue>(_command, _canExecute, value);
new InvokeCommandInfo<TCommand, TValue>(Command, CanExecute, value);
}
private static class InvokeCommandInfo

Просмотреть файл

@ -6,6 +6,7 @@
<RootNamespace>ReactiveUI</RootNamespace>
<Description>A MVVM framework that integrates with the Reactive Extensions for .NET to create elegant, testable User Interfaces that run on any mobile or desktop platform. Supports Xamarin.iOS, Xamarin.Android, Xamarin.Mac, Xamarin Forms, WPF, Windows Forms, Windows Phone 8.1, Windows Store and Universal Windows Platform (UWP).</Description>
<PackageId>ReactiveUI</PackageId>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -20,6 +20,11 @@ namespace ReactiveUI
/// <inheritdoc/>
public void Register(Action<Func<object>, Type> registerFunction)
{
if (registerFunction == null)
{
throw new ArgumentNullException(nameof(registerFunction));
}
registerFunction(() => new INPCObservableForProperty(), typeof(ICreatesObservableForProperty));
registerFunction(() => new IROObservableForProperty(), typeof(ICreatesObservableForProperty));
registerFunction(() => new POCOObservableForProperty(), typeof(ICreatesObservableForProperty));

Просмотреть файл

@ -25,27 +25,21 @@ namespace ReactiveUI
/// </summary>
public class MessageBus : IMessageBus
{
private static IMessageBus current = new MessageBus();
private readonly Dictionary<(Type type, string contract), NotAWeakReference> _messageBus =
new Dictionary<(Type type, string contract), NotAWeakReference>();
private readonly Dictionary<Tuple<Type, string>, NotAWeakReference> _messageBus =
new Dictionary<Tuple<Type, string>, NotAWeakReference>();
private readonly IDictionary<Tuple<Type, string>, IScheduler> _schedulerMappings =
new Dictionary<Tuple<Type, string>, IScheduler>();
private readonly IDictionary<(Type type, string contract), IScheduler> _schedulerMappings =
new Dictionary<(Type type, string contract), IScheduler>();
/// <summary>
/// Gets or sets the Current MessageBus.
/// </summary>
public static IMessageBus Current
{
get => current;
set => current = value;
}
public static IMessageBus Current { get; set; } = new MessageBus();
/// <summary>
/// Registers a scheduler for the type, which may be specified at runtime, and the contract.
/// </summary>
/// <remarks>If a scheduler is already registered for the specified runtime and contract, this will overrwrite the existing registration.</remarks>
/// <remarks>If a scheduler is already registered for the specified runtime and contract, this will overwrite the existing registration.</remarks>
/// <typeparam name="T">The type of the message to listen to.</typeparam>
/// <param name="scheduler">The scheduler on which to post the
/// notifications for the specified type and contract. CurrentThreadScheduler by default.</param>
@ -54,7 +48,7 @@ namespace ReactiveUI
/// only used for one purpose, leave this as null.</param>
public void RegisterScheduler<T>(IScheduler scheduler, string contract = null)
{
_schedulerMappings[new Tuple<Type, string>(typeof(T), contract)] = scheduler;
_schedulerMappings[(typeof(T), contract)] = scheduler;
}
/// <summary>
@ -121,7 +115,15 @@ namespace ReactiveUI
/// <returns>a Disposable.</returns>
public IDisposable RegisterMessageSource<T>(
IObservable<T> source,
string contract = null) => source.Subscribe(SetupSubjectIfNecessary<T>(contract));
string contract = null)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Subscribe(SetupSubjectIfNecessary<T>(contract));
}
/// <summary>
/// Sends a single message using the specified Type and contract.
@ -145,8 +147,7 @@ namespace ReactiveUI
WithMessageBus(typeof(T), contract, (mb, tuple) =>
{
NotAWeakReference subjRef;
if (mb.TryGetValue(tuple, out subjRef) && subjRef.IsAlive)
if (mb.TryGetValue(tuple, out NotAWeakReference subjRef) && subjRef.IsAlive)
{
ret = (ISubject<T>)subjRef.Target;
return;
@ -162,11 +163,11 @@ namespace ReactiveUI
private void WithMessageBus(
Type type,
string contract,
Action<Dictionary<Tuple<Type, string>, NotAWeakReference>, Tuple<Type, string>> block)
Action<Dictionary<(Type type, string contract), NotAWeakReference>, (Type type, string contract)> block)
{
lock (_messageBus)
{
var tuple = new Tuple<Type, string>(type, contract);
var tuple = (type, contract);
block(_messageBus, tuple);
if (_messageBus.ContainsKey(tuple) && !_messageBus[tuple].IsAlive)
{
@ -175,10 +176,9 @@ namespace ReactiveUI
}
}
private IScheduler GetScheduler(Tuple<Type, string> tuple)
private IScheduler GetScheduler((Type type, string contract) tuple)
{
IScheduler scheduler;
_schedulerMappings.TryGetValue(tuple, out scheduler);
_schedulerMappings.TryGetValue(tuple, out IScheduler scheduler);
return scheduler ?? CurrentThreadScheduler.Instance;
}
}

Просмотреть файл

@ -24,21 +24,26 @@ namespace ReactiveUI
/// while the ViewModel has focus, and cleans up when the ViewModel
/// loses focus.
/// </summary>
/// <param name="this">The ViewModel to watch for focus changes.</param>
/// <param name="item">The ViewModel to watch for focus changes.</param>
/// <param name="onNavigatedTo">Called when the ViewModel is navigated
/// to - return an IDisposable that cleans up all of the things that are
/// configured in the method.</param>
/// <returns>An IDisposable that lets you disconnect the entire process
/// earlier than normal.</returns>
public static IDisposable WhenNavigatedTo(this IRoutableViewModel @this, Func<IDisposable> onNavigatedTo)
public static IDisposable WhenNavigatedTo(this IRoutableViewModel item, Func<IDisposable> onNavigatedTo)
{
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
IDisposable inner = null;
var router = @this.HostScreen.Router;
var router = item.HostScreen.Router;
var navigationStackChanged = router.NavigationChanged.CountChanged();
return navigationStackChanged.Subscribe(_ =>
{
if (router.GetCurrentViewModel() == @this)
if (router.GetCurrentViewModel() == item)
{
inner?.Dispose();
@ -62,21 +67,26 @@ namespace ReactiveUI
/// the navigation stack and then reused later, you must call this method
/// and resubscribe each time it is reused.
/// </summary>
/// <param name="this">The viewmodel to watch for navigation changes.</param>
/// <param name="item">The viewmodel to watch for navigation changes.</param>
/// <returns>An IObservable{Unit} that signals when the ViewModel has
/// been added or brought to the top of the navigation stack. The
/// observable completes when the ViewModel is no longer a part of the
/// navigation stack.</returns>
public static IObservable<Unit> WhenNavigatedToObservable(this IRoutableViewModel @this)
public static IObservable<Unit> WhenNavigatedToObservable(this IRoutableViewModel item)
{
var router = @this.HostScreen.Router;
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
var router = item.HostScreen.Router;
var navigationStackChanged = router.NavigationChanged.CountChanged();
var itemRemoved = navigationStackChanged
.Where(x => x.Any(change => change.Reason == ListChangeReason.Remove && change.Item.Current == @this));
.Where(x => x.Any(change => change.Reason == ListChangeReason.Remove && change.Item.Current == item));
return navigationStackChanged
.Where(_ => router.GetCurrentViewModel() == @this)
.Where(_ => router.GetCurrentViewModel() == item)
.Select(_ => Unit.Default)
.TakeUntil(itemRemoved);
}
@ -91,21 +101,26 @@ namespace ReactiveUI
/// the navigation stack and then reused later, you must call this method
/// and resubscribe each time it is reused.
/// </summary>
/// /// <param name="this">The viewmodel to watch for navigation changes.</param>
/// /// <param name="item">The viewmodel to watch for navigation changes.</param>
/// <returns>An IObservable{Unit} that signals when the ViewModel is no
/// longer the topmost ViewModel in the navigation stack. The observable
/// completes when the ViewModel is no longer a part of the navigation
/// stack.</returns>
public static IObservable<Unit> WhenNavigatingFromObservable(this IRoutableViewModel @this)
public static IObservable<Unit> WhenNavigatingFromObservable(this IRoutableViewModel item)
{
var router = @this.HostScreen.Router;
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
var router = item.HostScreen.Router;
var navigationStackChanged = router.NavigationChanged.CountChanged();
bool StackIsCleared(Change<IRoutableViewModel> change) => change.Reason == ListChangeReason.Clear;
bool ThisViewModelIsRemoved(Change<IRoutableViewModel> change) => NavigationStackRemovalOperations.Contains(change.Reason) && change.Item.Current == @this;
bool ThisViewModelIsRemoved(Change<IRoutableViewModel> change) => NavigationStackRemovalOperations.Contains(change.Reason) && change.Item.Current == item;
var itemRemoved = navigationStackChanged.Where(x => x.Any(change => StackIsCleared(change) || ThisViewModelIsRemoved(change)));
var viewModelsChanged = navigationStackChanged.Scan(new IRoutableViewModel[2], (previous, current) => new[] { previous[1], router.GetCurrentViewModel() });
return viewModelsChanged
.Where(x => x[0] == @this)
.Where(x => x[0] == item)
.Select(_ => Unit.Default)
.TakeUntil(itemRemoved);
}

Просмотреть файл

@ -16,22 +16,32 @@ namespace ReactiveUI
/// Locate the first ViewModel in the stack that matches a certain Type.
/// </summary>
/// <typeparam name="T">The view model type.</typeparam>
/// <param name="this">The routing state.</param>
/// <param name="item">The routing state.</param>
/// <returns>The matching ViewModel or null if none exists.</returns>
public static T FindViewModelInStack<T>(this RoutingState @this)
public static T FindViewModelInStack<T>(this RoutingState item)
where T : IRoutableViewModel
{
return @this.NavigationStack.Reverse().OfType<T>().FirstOrDefault();
if (item == null)
{
throw new System.ArgumentNullException(nameof(item));
}
return item.NavigationStack.Reverse().OfType<T>().FirstOrDefault();
}
/// <summary>
/// Returns the currently visible ViewModel.
/// </summary>
/// <param name="this">The routing state.</param>
/// <param name="item">The routing state.</param>
/// <returns>The matching ViewModel or null if none exists.</returns>
public static IRoutableViewModel GetCurrentViewModel(this RoutingState @this)
public static IRoutableViewModel GetCurrentViewModel(this RoutingState item)
{
return @this.NavigationStack.LastOrDefault();
if (item == null)
{
throw new System.ArgumentNullException(nameof(item));
}
return item.NavigationStack.LastOrDefault();
}
}
}

Просмотреть файл

@ -19,12 +19,12 @@ namespace ReactiveUI
/// Observe changes to the AppState of a class derived from ISuspensionHost.
/// </summary>
/// <typeparam name="T">The observable type.</typeparam>
/// <param name="this">The suspension host.</param>
/// <param name="item">The suspension host.</param>
/// <returns>An observable of the app state.</returns>
public static IObservable<T> ObserveAppState<T>(this ISuspensionHost @this)
public static IObservable<T> ObserveAppState<T>(this ISuspensionHost item)
where T : class
{
return @this.WhenAny(x => x.AppState, x => (T)x.Value)
return item.WhenAny(x => x.AppState, x => (T)x.Value)
.Where(x => x != null);
}
@ -32,42 +32,52 @@ namespace ReactiveUI
/// Get the current App State of a class derived from ISuspensionHost.
/// </summary>
/// <typeparam name="T">The app state type.</typeparam>
/// <param name="this">The suspenstion host.</param>
/// <param name="item">The suspension host.</param>
/// <returns>The app state.</returns>
public static T GetAppState<T>(this ISuspensionHost @this)
public static T GetAppState<T>(this ISuspensionHost item)
{
return (T)@this.AppState;
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
return (T)item.AppState;
}
/// <summary>
/// Setup our suspension driver for a class derived off ISuspensionHost interface.
/// This will make your suspension host respond to suspend and resume requests.
/// </summary>
/// <param name="this">The suspension host.</param>
/// <param name="item">The suspension host.</param>
/// <param name="driver">The suspension driver.</param>
/// <returns>A disposable which will stop responding to Suspend and Resume requests.</returns>
public static IDisposable SetupDefaultSuspendResume(this ISuspensionHost @this, ISuspensionDriver driver = null)
public static IDisposable SetupDefaultSuspendResume(this ISuspensionHost item, ISuspensionDriver driver = null)
{
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
var ret = new CompositeDisposable();
driver = driver ?? Locator.Current.GetService<ISuspensionDriver>();
ret.Add(@this.ShouldInvalidateState
ret.Add(item.ShouldInvalidateState
.SelectMany(_ => driver.InvalidateState())
.LoggedCatch(@this, Observables.Unit, "Tried to invalidate app state")
.Subscribe(_ => @this.Log().Info("Invalidated app state")));
.LoggedCatch(item, Observables.Unit, "Tried to invalidate app state")
.Subscribe(_ => item.Log().Info("Invalidated app state")));
ret.Add(@this.ShouldPersistState
.SelectMany(x => driver.SaveState(@this.AppState).Finally(x.Dispose))
.LoggedCatch(@this, Observables.Unit, "Tried to persist app state")
.Subscribe(_ => @this.Log().Info("Persisted application state")));
ret.Add(item.ShouldPersistState
.SelectMany(x => driver.SaveState(item.AppState).Finally(x.Dispose))
.LoggedCatch(item, Observables.Unit, "Tried to persist app state")
.Subscribe(_ => item.Log().Info("Persisted application state")));
ret.Add(Observable.Merge(@this.IsResuming, @this.IsLaunchingNew)
ret.Add(Observable.Merge(item.IsResuming, item.IsLaunchingNew)
.SelectMany(x => driver.LoadState())
.LoggedCatch(
@this,
Observable.Defer(() => Observable.Return(@this.CreateNewAppState())),
item,
Observable.Defer(() => Observable.Return(item.CreateNewAppState())),
"Failed to restore app state from storage, creating from scratch")
.Subscribe(x => @this.AppState = x ?? @this.CreateNewAppState()));
.Subscribe(x => item.AppState = x ?? item.CreateNewAppState()));
return ret;
}

Просмотреть файл

@ -21,6 +21,7 @@
<Rule Id="CA1063" Action="Error" />
<Rule Id="CA1065" Action="Error" />
<Rule Id="CA1301" Action="Error" />
<Rule Id="CA1303" Action="None" />
<Rule Id="CA1308" Action="None" />
<Rule Id="CA1400" Action="Error" />
<Rule Id="CA1401" Action="Error" />
@ -33,6 +34,7 @@
<Rule Id="CA1821" Action="Error" />
<Rule Id="CA1900" Action="Error" />
<Rule Id="CA1901" Action="Error" />
<Rule Id="CA2000" Action="None" />
<Rule Id="CA2002" Action="Error" />
<Rule Id="CA2100" Action="Error" />
<Rule Id="CA2101" Action="Error" />

Просмотреть файл

@ -21,6 +21,7 @@
<Rule Id="CA1063" Action="Error" />
<Rule Id="CA1065" Action="Error" />
<Rule Id="CA1301" Action="Error" />
<Rule Id="CA1303" Action="None" />
<Rule Id="CA1305" Action="None" />
<Rule Id="CA1307" Action="None" />
<Rule Id="CA1308" Action="None" />
@ -31,12 +32,14 @@
<Rule Id="CA1405" Action="Error" />
<Rule Id="CA1410" Action="Error" />
<Rule Id="CA1415" Action="Error" />
<Rule Id="CA1062" Action="None" />
<Rule Id="CA1507" Action="Error" />
<Rule Id="CA1707" Action="None" />
<Rule Id="CA1821" Action="Error" />
<Rule Id="CA1822" Action="None" />
<Rule Id="CA1900" Action="Error" />
<Rule Id="CA1901" Action="Error" />
<Rule Id="CA2000" Action="None" />
<Rule Id="CA2002" Action="Error" />
<Rule Id="CA2100" Action="Error" />
<Rule Id="CA2101" Action="Error" />