/// <summary> /// Determines the conventions for a view model and a set of UI elements. /// </summary> /// <param name="viewModelDescription">The view model description.</param> /// <param name="elementDescriptions">The element descriptions.</param> /// <returns>The applicable conventions.</returns> public virtual IEnumerable <IViewApplicable> DetermineConventions(IViewModelDescription viewModelDescription, IEnumerable <ElementDescription> elementDescriptions) { foreach (var elementDescription in elementDescriptions) { bool found = false; foreach (var set in viewConventions) { var applications = set.GetApplications(this, viewModelDescription, elementDescription); foreach (var application in applications) { yield return(application); } if (applications.Any()) { found = true; break; } } if (!found) { Log.Warn("No convention matched for {0}.", elementDescription.Name); } } }
/// <summary> /// Creates the application of the convention. /// </summary> /// <param name="conventionManager">The convention manager.</param> /// <param name="description">The description.</param> /// <param name="element">The element.</param> /// <param name="property">The property.</param> /// <returns>The convention application.</returns> public override IViewApplicable TryCreateApplication(IConventionManager conventionManager, IViewModelDescription description, ElementDescription element, PropertyInfo property) { var expectedPath = DeterminePropertyPath(element.Name); string correctedPath; var boundProperty = GetBoundProperty(property, expectedPath, out correctedPath); if (boundProperty == null) { return(null); } Log.Info("Binding convention matched for {0}.", element.Name); var setMethod = boundProperty.GetSetMethod(); var canWriteToProperty = boundProperty.CanWrite && setMethod != null && setMethod.IsPublic; return(new ApplicableBinding( element, element.Convention.BindableProperty, correctedPath, canWriteToProperty ? BindingMode.TwoWay : BindingMode.OneWay, ShouldValidate(boundProperty), false, conventionManager.GetValueConverter(element.Convention.BindableProperty, boundProperty.PropertyType) )); }
/// <summary> /// Creates the application of the convention. /// </summary> /// <param name="conventionManager">The convention manager.</param> /// <param name="description">The description.</param> /// <param name="element">The element.</param> /// <param name="property">The property.</param> /// <returns>The convention application.</returns> public override IViewApplicable TryCreateApplication(IConventionManager conventionManager, IViewModelDescription description, ElementDescription element, PropertyInfo property) { var expectedPath = DeterminePropertyPath(element.Name); string correctedPath; var boundProperty = GetBoundProperty(property, expectedPath, out correctedPath); if (boundProperty == null || !ItemsControlType.IsAssignableFrom(element.Type)) { return(null); } string path = null; DependencyProperty bindableProperty = null; BindingMode mode = BindingMode.OneWay; bool checkTemplate = ShouldCheckTemplate(property); IValueConverter converter = null; if (SelectorControlType.IsAssignableFrom(element.Type)) { string selectionPath; PropertyInfo selectionProperty; if (TryGetByPattern(property, correctedPath, out selectionPath, out selectionProperty, originalName => originalName.MakeSingular(), (info, baseName) => string.Compare(info.Name, "Current" + baseName, StringComparison.CurrentCultureIgnoreCase) == 0 || string.Compare(info.Name, "Active" + baseName, StringComparison.CurrentCultureIgnoreCase) == 0 || string.Compare(info.Name, "Selected" + baseName, StringComparison.CurrentCultureIgnoreCase) == 0 )) { path = selectionPath; bindableProperty = Selector.SelectedItemProperty; mode = selectionProperty.CanWrite ? BindingMode.TwoWay : BindingMode.OneWay; converter = conventionManager.GetValueConverter(bindableProperty, boundProperty.PropertyType); Log.Info("Selector binding convention added to {0}.", element.Name); } else { return(null); } } #if !SILVERLIGHT else if (HeaderedItemsControlType.IsAssignableFrom(element.Type)) { string headerPath; PropertyInfo headerProperty; if (TryGetByPattern(property, correctedPath, out headerPath, out headerProperty, originalName => originalName, (info, baseName) => string.Compare(info.Name, baseName + "Header", StringComparison.CurrentCultureIgnoreCase) == 0 )) { path = headerPath; bindableProperty = HeaderedItemsControl.HeaderProperty; mode = headerProperty.CanWrite ? BindingMode.TwoWay : BindingMode.OneWay; converter = conventionManager.GetValueConverter(bindableProperty, headerProperty.PropertyType); Log.Info("Header binding convention added to {0}.", element.Name); } else { return(null); } } #endif return(new ApplicableBinding( element, bindableProperty, path, mode, false, checkTemplate, converter )); }
/// <summary> /// Creates the application of the convention. /// </summary> /// <param name="conventionManager">The convention manager.</param> /// <param name="description">The description.</param> /// <param name="element">The element.</param> /// <param name="action">The action.</param> /// <returns></returns> public override IViewApplicable TryCreateApplication(IConventionManager conventionManager, IViewModelDescription description, ElementDescription element, IAction action) { if (string.Compare(element.Name, action.Name, StringComparison.CurrentCultureIgnoreCase) != 0) { return(null); } var message = CreateActionMessage(action); Log.Info("Action convention matched for {0}.", element.Name); return(new ApplicableAction(element.Name, null, message)); }
/// <summary> /// Gets the applications. /// </summary> /// <param name="conventionManager">The convention manager.</param> /// <param name="viewModelDescription">The view model description.</param> /// <param name="elementDescription">The element description.</param> /// <returns>The applications.</returns> public IEnumerable <IViewApplicable> GetApplications(IConventionManager conventionManager, IViewModelDescription viewModelDescription, ElementDescription elementDescription) { return(from convention in conventions from target in getTargets(viewModelDescription) let application = convention.TryCreateApplication(conventionManager, viewModelDescription, elementDescription, target) where application != null select application); }
/// <summary> /// Tries to creates the application of the convention. /// </summary> /// <param name="conventionManager">The convention manager.</param> /// <param name="description">The description.</param> /// <param name="element">The element.</param> /// <param name="target">The target.</param> /// <returns> /// The convention application, or null if not applicable /// </returns> public override IViewApplicable TryCreateApplication(IConventionManager conventionManager, IViewModelDescription description, ElementDescription element, PropertyInfo target) { var exptectedPath = DeterminePropertyPath(element.Name); var index = exptectedPath.LastIndexOf("."); if (index == -1) { return(null); } var propertyPath = exptectedPath.Substring(0, index); string correctedPath; var actualTarget = GetBoundProperty(target, propertyPath, out correctedPath); if (actualTarget == null) { return(null); } var actionName = exptectedPath.Substring(index + 1); var subDescription = ViewModelDescriptionFactory.Create(actualTarget.PropertyType); var action = subDescription.Actions.FirstOrDefault(x => string.Compare(x.Name, actionName, StringComparison.CurrentCultureIgnoreCase) == 0); if (action == null) { return(null); } var message = CreateActionMessage(action); Log.Info("Sub action convention matched for {0} on {1}.", element.Name, correctedPath); return(new ApplicableAction( element.Name, correctedPath, message )); }
/// <summary> /// Determines the conventions for the specified view and view model description. /// </summary> /// <param name="conventionManager">The convention manager.</param> /// <param name="viewModelDescription">The view model description.</param> /// <param name="view">The view.</param> /// <returns>The applicalble conventions.</returns> public static IEnumerable<IViewApplicable> DetermineConventions(this IConventionManager conventionManager, IViewModelDescription viewModelDescription, DependencyObject view) { return conventionManager.DetermineConventions(viewModelDescription, SelectElementsToInspect(conventionManager, view)); }
/// <summary> /// Determines the conventions for the specified view and view model description. /// </summary> /// <param name="conventionManager">The convention manager.</param> /// <param name="viewModelDescription">The view model description.</param> /// <param name="view">The view.</param> /// <returns>The applicalble conventions.</returns> public static IEnumerable <IViewApplicable> DetermineConventions(this IConventionManager conventionManager, IViewModelDescription viewModelDescription, DependencyObject view) { return(conventionManager.DetermineConventions(viewModelDescription, SelectElementsToInspect(conventionManager, view))); }