using System; using System.Collections.Generic; using System.Windows; using System.Windows.Input; using System.Windows.Markup; using Caliburn.Events; using Caliburn.Messaging; using Caliburn.Metadata; using Caliburn.Services; namespace Caliburn.Views { public class ViewManager : IViewManager { #region Fields protected readonly Dictionary _elementDefaults = new Dictionary(); #endregion #region IViewManager Members public virtual void RegisterDefaults(ElementDefaults defaults) { _elementDefaults[defaults.ElementType] = defaults; } public virtual void AddMessageSource(DependencyObject source, MessageBase message) { if (source == null) throw new CaliburnException("Attempted to register invalid message source."); InitializeMessage(source, message); if (message.Trigger == null) { ElementDefaults defaults; Type sourceType = source.GetType(); if (_elementDefaults.TryGetValue(sourceType, out defaults)) WireSender(source, message, defaults.DefaultEventName); else throw new CaliburnException("Could not determine default event for type: " + sourceType.Name); } else { InputGesture gesture = message.Trigger as InputGesture; if (gesture != null) { CreateInputBinding( source, message.CreateMessageCommand(source), gesture ); } else WireSender(source, message, message.Trigger.ToString()); } } public virtual ElementDefaults GetDefaults(Type elementType) { ElementDefaults defaults; _elementDefaults.TryGetValue(elementType, out defaults); return defaults; } #region Helper Methods protected virtual void WireSender(DependencyObject source, MessageBase message, string eventName) { IEventHandler eventHandler = LooseEvent.Wire(source, eventName); eventHandler.SetAction( delegate { message.Send(source); } ); } protected virtual void CreateInputBinding(DependencyObject source, ICommand command, InputGesture gesture) { UIElement element = source as UIElement; if(element == null) throw new CaliburnException( "You cannot set an input binding on a type that does not derive from UIElement."); element.InputBindings.Add( new InputBinding( command, gesture ) ); } protected virtual void InitializeMessage(DependencyObject source, MessageBase message) { if(message.NameScope == null) message.NameScope = FindNameScopeRecursive(source); foreach(Parameter parameter in message.Parameters) { NameScope.SetNameScope(parameter, message.NameScope); } } protected virtual INameScope FindNameScopeRecursive(DependencyObject dependencyObject) { if(dependencyObject == null) return null; INameScope scope = NameScope.GetNameScope(dependencyObject); if(scope != null) return scope; else return FindNameScopeRecursive(LogicalTreeHelper.GetParent(dependencyObject)); } #endregion #endregion } }