zoukankan      html  css  js  c++  java
  • Caliburn笔记Presenter的管理(wpf框架)


    回头来看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

  • 相关阅读:
    百度地图(25)-GL 标注
    百度地图(24)-GL 地图自定义样式
    百度地图(4)-自定义地图样式
    百度地图(23)-GL 地图属性
    百度地图(22)-GL 添加地图控件
    百度地图(21)-GL 初始化地图
    百度地图(20)-路书
    百度地图(19)-沿线移动
    百度地图(18)-海量数据
    百度地图(17)-热力图
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1634054.html
Copyright © 2011-2022 走看看