Skip to content

Commit

Permalink
feat: more flexible WireUpControls implementation (#1250)
Browse files Browse the repository at this point in the history
fixes #1234, #1231, #1227
  • Loading branch information
Qonstrukt authored and kentcb committed Feb 20, 2017
1 parent bf6e1a4 commit 01c6af2
Showing 1 changed file with 74 additions and 17 deletions.
91 changes: 74 additions & 17 deletions src/ReactiveUI/Android/ControlFetcherMixin.cs
Expand Up @@ -3,7 +3,6 @@
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using Android.App;
using Android.Views;
using Java.Interop;
Expand Down Expand Up @@ -75,15 +74,14 @@ public static T GetControl<T>(this Fragment This, [CallerMemberName]string prope
/// <summary>
///
/// </summary>
public static void WireUpControls(this ILayoutViewHost This)
public static void WireUpControls(this ILayoutViewHost This, ResolveStrategy resolveMembers = ResolveStrategy.Implicit)
{
var members = This.GetType().GetRuntimeProperties()
.Where(m => m.PropertyType.IsSubclassOf(typeof(View)));
var members = This.getWireUpMembers(resolveMembers);

members.ToList().ForEach(m => {
try {
// Find the android control with the same name
var view = This.View.getControlInternal(m.PropertyType, m.Name);
var view = This.View.getControlInternal(m.PropertyType, m.getResourceName());
// Set the activity field's value to the view with that identifier
m.SetValue(This, view);
Expand All @@ -97,15 +95,14 @@ public static void WireUpControls(this ILayoutViewHost This)
/// <summary>
///
/// </summary>
public static void WireUpControls(this View This)
public static void WireUpControls(this View This, ResolveStrategy resolveMembers = ResolveStrategy.Implicit)
{
var members = This.GetType().GetRuntimeProperties()
.Where(m => m.PropertyType.IsSubclassOf(typeof(View)));
var members = This.getWireUpMembers(resolveMembers);

members.ToList().ForEach(m => {
try {
// Find the android control with the same name
var view = This.getControlInternal(m.PropertyType, m.Name);
var view = This.getControlInternal(m.PropertyType, m.getResourceName());
// Set the activity field's value to the view with that identifier
m.SetValue(This, view);
Expand All @@ -121,15 +118,14 @@ public static void WireUpControls(this View This)
/// </summary>
/// <param name="This"></param>
/// <param name="inflatedView"></param>
public static void WireUpControls(this Fragment This, View inflatedView)
public static void WireUpControls(this Fragment This, View inflatedView, ResolveStrategy resolveMembers = ResolveStrategy.Implicit)
{
var members = This.GetType().GetRuntimeProperties()
.Where(m => m.PropertyType.IsSubclassOf(typeof(View)));
var members = This.getWireUpMembers(resolveMembers);

members.ToList().ForEach(m => {
try {
// Find the android control with the same name from the view
var view = inflatedView.getControlInternal(m.PropertyType, m.Name);
var view = inflatedView.getControlInternal(m.PropertyType, m.getResourceName());
// Set the activity field's value to the view with that identifier
m.SetValue(This, view);
Expand All @@ -143,15 +139,14 @@ public static void WireUpControls(this Fragment This, View inflatedView)
/// <summary>
///
/// </summary>
public static void WireUpControls(this Activity This)
public static void WireUpControls(this Activity This, ResolveStrategy resolveMembers = ResolveStrategy.Implicit)
{
var members = This.GetType().GetRuntimeProperties()
.Where(m => m.PropertyType.IsSubclassOf(typeof(View)));
var members = This.getWireUpMembers(resolveMembers);

members.ToList().ForEach(m => {
try {
// Find the android control with the same name
var view = This.getControlInternal(m.PropertyType, m.Name);
var view = This.getControlInternal(m.PropertyType, m.getResourceName());
// Set the activity field's value to the view with that identifier
m.SetValue(This, view);
Expand Down Expand Up @@ -188,5 +183,67 @@ static View getCachedControl(string propertyName, object rootView, Func<View> fe
ourViewCache.Add(propertyName, ret);
return ret;
}

static string getResourceName(this PropertyInfo member)
{
var resourceNameOverride = member.GetCustomAttribute<WireUpResourceAttribute>()?.ResourceNameOverride;
return resourceNameOverride ?? member.Name;
}

static IEnumerable<PropertyInfo> getWireUpMembers(this object This, ResolveStrategy resolveStrategy)
{
var members = This.GetType().GetRuntimeProperties();

switch (resolveStrategy) {
default:
case ResolveStrategy.Implicit:
return members.Where(m => m.PropertyType.IsSubclassOf(typeof(View))
|| m.GetCustomAttribute<WireUpResourceAttribute>(true) != null);

case ResolveStrategy.ExplicitOptIn:
return members.Where(m => m.GetCustomAttribute<WireUpResourceAttribute>(true) != null);

case ResolveStrategy.ExplicitOptOut:
return members.Where(m => typeof(View).IsAssignableFrom(m.PropertyType)
&& m.GetCustomAttribute<IgnoreResourceAttribute>(true) == null);
}
}


public enum ResolveStrategy
{
/// <summary>
/// Resolve all properties that use a subclass of View.
/// </summary>
Implicit,
/// <summary>
/// Resolve only properties with an WireUpResource attribute.
/// </summary>
ExplicitOptIn,
/// <summary>
/// Resolve all View properties and those that use a subclass of View, except those with an IgnoreResource attribute.
/// </summary>
ExplicitOptOut
}
}


public class WireUpResourceAttribute : Attribute
{
public readonly string ResourceNameOverride;

public WireUpResourceAttribute()
{
}

public WireUpResourceAttribute(string resourceName)
{
ResourceNameOverride = resourceName;
}
}


public class IgnoreResourceAttribute : Attribute
{
}
}

0 comments on commit 01c6af2

Please sign in to comment.