diff --git a/src/Caliburn.Micro.Platform/ViewModelBinder.cs b/src/Caliburn.Micro.Platform/ViewModelBinder.cs
index 49032030..3c8ad649 100644
--- a/src/Caliburn.Micro.Platform/ViewModelBinder.cs
+++ b/src/Caliburn.Micro.Platform/ViewModelBinder.cs
@@ -11,6 +11,7 @@ namespace Caliburn.Micro
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
+ using System.Text;
#if XFORMS
using UIElement = global::Xamarin.Forms.Element;
using FrameworkElement = global::Xamarin.Forms.VisualElement;
@@ -41,7 +42,8 @@ namespace Caliburn.Micro
///
/// Binds a view to a view model.
///
- public static class ViewModelBinder {
+ public static class ViewModelBinder
+ {
const string AsyncSuffix = "Async";
static readonly ILog Log = LogManager.GetLog(typeof(ViewModelBinder));
@@ -75,7 +77,8 @@ public static class ViewModelBinder {
///
/// The view to check.
/// Whether or not conventions should be applied to the view.
- public static bool ShouldApplyConventions(FrameworkElement view) {
+ public static bool ShouldApplyConventions(FrameworkElement view)
+ {
var overriden = View.GetApplyConventions(view);
return overriden.GetValueOrDefault(ApplyConventionsByDefault);
}
@@ -84,30 +87,35 @@ public static bool ShouldApplyConventions(FrameworkElement view) {
/// Creates data bindings on the view's controls based on the provided properties.
///
/// Parameters include named Elements to search through and the type of view model to determine conventions for. Returns unmatched elements.
- public static Func, Type, IEnumerable> BindProperties = (namedElements, viewModelType) => {
+ public static Func, Type, IEnumerable> BindProperties = (namedElements, viewModelType) =>
+ {
var unmatchedElements = new List();
#if !XFORMS && !MAUI
- foreach (var element in namedElements) {
+ foreach (var element in namedElements)
+ {
var cleanName = element.Name.Trim('_');
var parts = cleanName.Split(new[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
var property = viewModelType.GetPropertyCaseInsensitive(parts[0]);
var interpretedViewModelType = viewModelType;
- for (int i = 1; i < parts.Length && property != null; i++) {
+ for (int i = 1; i < parts.Length && property != null; i++)
+ {
interpretedViewModelType = property.PropertyType;
property = interpretedViewModelType.GetPropertyCaseInsensitive(parts[i]);
}
- if (property == null) {
+ if (property == null)
+ {
unmatchedElements.Add(element);
Log.Info("Binding Convention Not Applied: Element {0} did not match a property.", element.Name);
continue;
}
var convention = ConventionManager.GetElementConvention(element.GetType());
- if (convention == null) {
+ if (convention == null)
+ {
unmatchedElements.Add(element);
Log.Warn("Binding Convention Not Applied: No conventions configured for {0}.", element.GetType());
continue;
@@ -121,10 +129,12 @@ public static bool ShouldApplyConventions(FrameworkElement view) {
convention
);
- if (applied) {
+ if (applied)
+ {
Log.Info("Binding Convention Applied: Element {0}.", element.Name);
}
- else {
+ else
+ {
Log.Info("Binding Convention Not Applied: Element {0} has existing binding.", element.Name);
unmatchedElements.Add(element);
}
@@ -138,7 +148,8 @@ public static bool ShouldApplyConventions(FrameworkElement view) {
/// Attaches instances of to the view's controls based on the provided methods.
///
/// Parameters include the named elements to search through and the type of view model to determine conventions for. Returns unmatched elements.
- public static Func, Type, IEnumerable> BindActions = (namedElements, viewModelType) => {
+ public static Func, Type, IEnumerable> BindActions = (namedElements, viewModelType) =>
+ {
var unmatchedElements = namedElements.ToList();
#if !XFORMS && !MAUI
#if WINDOWS_UWP || XFORMS || MAUI
@@ -146,21 +157,24 @@ public static bool ShouldApplyConventions(FrameworkElement view) {
#else
var methods = viewModelType.GetMethods();
#endif
-
- foreach (var method in methods) {
- Log.Info($"Searching for methods control {method.Name} unmatchedElements count {unmatchedElements.Count}");
+
+ foreach (var method in methods)
+ {
+ Log.Info($"Searching for methods control {method.Name} unmatchedElements count {unmatchedElements.Count}");
var foundControl = unmatchedElements.FindName(method.Name);
- if (foundControl == null && IsAsyncMethod(method)) {
+ if (foundControl == null && IsAsyncMethod(method))
+ {
var methodNameWithoutAsyncSuffix = method.Name.Substring(0, method.Name.Length - AsyncSuffix.Length);
foundControl = unmatchedElements.FindName(methodNameWithoutAsyncSuffix);
}
- if(foundControl == null) {
+ if (foundControl == null)
+ {
Log.Info("Action Convention Not Applied: No actionable element for {0}. {1}", method.Name, unmatchedElements.Count);
- foreach(var element in unmatchedElements)
+ foreach (var element in unmatchedElements)
{
- Log.Info($"Unnamed element {element.Name}");
+ Log.Info($"Unnamed element {element.Name}");
}
continue;
}
@@ -176,25 +190,31 @@ public static bool ShouldApplyConventions(FrameworkElement view) {
}
#endif
- var message = method.Name;
var parameters = method.GetParameters();
+ var messageBuilder = new StringBuilder(method.Name);
- if (parameters.Length > 0) {
- message += "(";
+ if (parameters.Length > 0)
+ {
+ messageBuilder.Append("(");
- foreach (var parameter in parameters) {
+ foreach (var parameter in parameters)
+ {
var paramName = parameter.Name;
var specialValue = "$" + paramName.ToLower();
if (MessageBinder.SpecialValues.ContainsKey(specialValue))
paramName = specialValue;
- message += paramName + ",";
+ messageBuilder.Append(paramName).Append(",");
}
- message = message.Remove(message.Length - 1, 1);
- message += ")";
+ // Remove the trailing comma
+ if (parameters.Length > 0)
+ messageBuilder.Length -= 1;
+ messageBuilder.Append(")");
+
}
+ var message = messageBuilder.ToString();
Log.Info("Action Convention Applied: Action {0} on element {1}.", method.Name, message);
Message.SetAttach(foundControl, message);
@@ -203,7 +223,8 @@ public static bool ShouldApplyConventions(FrameworkElement view) {
return unmatchedElements;
};
- static bool IsAsyncMethod(MethodInfo method) {
+ static bool IsAsyncMethod(MethodInfo method)
+ {
return typeof(Task).GetTypeInfo().IsAssignableFrom(method.ReturnType.GetTypeInfo()) &&
method.Name.EndsWith(AsyncSuffix, StringComparison.OrdinalIgnoreCase);
}
@@ -217,13 +238,16 @@ static bool IsAsyncMethod(MethodInfo method) {
/// Binds the specified viewModel to the view.
///
///Passes the the view model, view and creation context (or null for default) to use in applying binding.
- public static Action