Caliburn笔记-Presenter的管理(wpf框架)
2009-12-28 14:08 Clingingboy 阅读(1051) 评论(0) 编辑 收藏 举报
回头来看caliburn是如何初始化程序界面
CaliburnApplication
CaliburnApplication继承自WPF的Application类,其初始化了caliburn的接口,同时提供了一个窗口管理的接口IWindowManager,与prism框架不同这个shell是非强制性的
一.初始化
///<summary> /// Raises the <see cref="E:System.Windows.Application.Startup"/> event. /// </summary> /// <param name="e">A <see cref="T:System.Windows.StartupEventArgs"/> that contains the event data.</param> protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); var rootModel = CreateRootModel(); if (rootModel == null) return; ShowMainWindow(rootModel); } /// <summary> /// Creates the root application model. /// </summary> /// <returns></returns> protected virtual object CreateRootModel() { return null; } /// <summary> /// Shows the main window based on the provided model. /// </summary> /// <param name="rootModel">The root model.</param> protected virtual void ShowMainWindow(object rootModel) { Container.GetInstance<IWindowManager>() .Show(rootModel, null, ExecuteShutdownModel); } /// <summary> /// Executes the shutdown model. /// </summary> /// <param name="subordinate">The subordinate.</param> /// <param name="completed">The completed.</param> protected virtual void ExecuteShutdownModel(ISubordinate subordinate, Action completed) { completed();
根据以上代码可得知,继承的类需要重写CreateRootModel和ExecuteShutdownModel方法.具体由IWindowManager负责处理
万事具备后IWindowManager负责初始化
初始化时容器可为Window也可以为UserControl,若是UserControl则会自动创建一个Window作为容器,但不建议这么做
/// <summary> /// Ensures the that the view is a window or provides one. /// </summary> /// <param name="model">The model.</param> /// <param name="view">The view.</param> /// <returns></returns> protected virtual Window EnsureWindow(object model, object view) { var window = view as Window; if(window == null) { window = new Window { Content = view, SizeToContent = SizeToContent.WidthAndHeight }; if(Application.Current != null && Application.Current.MainWindow != null) { window.Owner = Application.Current.MainWindow; } var presenter = model as IPresenter; if(presenter != null) window.Title = presenter.DisplayName; } else if (Application.Current != null && Application.Current.MainWindow != null) { if(Application.Current.MainWindow != window) window.Owner = Application.Current.MainWindow; } return window; }
初始化Presenter
/// <summary> /// Shows a window for the specified model. /// </summary> /// <param name="rootModel">The root model.</param> /// <param name="context">The context.</param> /// <param name="handleShutdownModel">The handle shutdown model.</param> public void Show(object rootModel, object context, Action<ISubordinate, Action> handleShutdownModel) { var window = CreateWindow(rootModel, context, handleShutdownModel); window.Show(); } /// <summary> /// Creates the window. /// </summary> /// <param name="rootModel">The root model.</param> /// <param name="context">The context.</param> /// <param name="handleShutdownModel">The handle shutdown model.</param> /// <returns></returns> protected Window CreateWindow(object rootModel, object context, Action<ISubordinate, Action> handleShutdownModel) { var view = EnsureWindow(rootModel, _viewStrategy.GetView(rootModel, null, context)); _binder.Bind(rootModel, view, context); var presenter = rootModel as IPresenter; if (presenter != null) { presenter.Initialize(); presenter.Activate(); view.Closing += (s, e) => OnShutdownAttempted(presenter, view, handleShutdownModel, e); view.Closed += delegate{ presenter.Deactivate(); presenter.Shutdown(); }; } return view; }
以上presenter的生命周期就比较明朗了.
IPresenterManager
IPresenterManager is an IPresenterHost that tracks a CurrentPresenter. Whenever the CurrentPresenter is changed, the old one is deactivated/shutdown and the new one is initialized/activated.
IPresenterManager可以将一个Presenter与另外一个Presenter关联起来,两者属于父子关系,即IPresenterNode的Parent属性(IPresenterHost),一下为重写的方法
#region override method /// <summary> /// Determines whether this instance can shutdown. /// </summary> /// <returns> /// <c>true</c> if this instance can shutdown; otherwise, <c>false</c>. /// </returns> public override bool CanShutdown() { if(_currentPresenter != null) return _currentPresenter.CanShutdown(); return true; } /// <summary> /// Initializes this instance. /// </summary> public override void Initialize() { if(!IsInitialized) { OnInitialize(); if(_currentPresenter != null) _currentPresenter.Initialize(); IsInitialized = true; } } /// <summary> /// Shuts down this instance. /// </summary> public override void Shutdown() { if(_currentPresenter != null) _currentPresenter.Shutdown(); OnShutdown(); } /// <summary> /// Activates this instance. /// </summary> public override void Activate() { if(!IsActive) { OnActivate(); if(_currentPresenter != null) _currentPresenter.Activate(); IsActive = true; } } /// <summary> /// Deactivates this instance. /// </summary> public override void Deactivate() { if(IsActive) { OnDeactivate(); if(_currentPresenter != null) _currentPresenter.Deactivate(); IsActive = false; } }
在设置新的Presenter时,首先会释放之前的Presenter
/// <summary> /// Shuts down the current presenter. /// </summary> /// <param name="completed">Called when the shutdown action is finished.</param> public virtual void ShutdownCurrent(Action<bool> completed) { if(_currentPresenter == null) { completed(true); return; } CanShutdownPresenter( _currentPresenter, isSuccess =>{ if(!isSuccess) { completed(false); return; } _currentPresenter.Deactivate(); _currentPresenter.Shutdown(); var node = _currentPresenter as IPresenterNode; if (node != null) node.Parent = null; _currentPresenter = null; if(!_changingThroughProperty) NotifyOfPropertyChange("CurrentPresenter"); completed(true); }); }
PresenterManager的Open方法会初始化关联的Presenter,并设置CurrentPresenter
/// <summary> /// Opens the specified presenter. /// </summary> /// <param name="presenter">The presenter.</param> /// <param name="completed">Called when the open action is finished.</param> public virtual void Open(IPresenter presenter, Action<bool> completed) { if(presenter == null) { completed(false); return; } Action successfulCompletion = () =>{ var node = presenter as IPresenterNode; if (node != null) node.Parent = this; presenter.Initialize(); presenter.Activate(); _currentPresenter = presenter; if(!_changingThroughProperty) NotifyOfPropertyChange("CurrentPresenter"); completed(true); }; if(_currentPresenter != null) { CanShutdownPresenter( _currentPresenter, isSuccess =>{ if(!isSuccess) { completed(false); return; } _currentPresenter.Deactivate(); _currentPresenter.Shutdown(); var node = _currentPresenter as IPresenterNode; if (node != null) node.Parent = null; successfulCompletion(); }); } else successfulCompletion(); }
多重Presenter管理
以上应用情景支持presenter的一开一关操作,也可以使用MultiPresenterManager和MultiPresenter这两个类进行管理,这样当设置CurrentPresenter时,则不会关闭之前的Presenter