客製化TeeeNode(一)-MVP

  • 1465
  • 0
  • 2010-07-19

摘要:客製化TeeeNode(使用泛型、多型、MVP)

傳統的UI呈現往往是使用左樹(TreeView)右資料的方式來做資料的編輯與顯示

1.左樹上的需求 可能會有

  • 雙擊開窗編輯
  • 單擊後於右方資料區呈現資料
  • 根據資料改變而改變樹上節點的顯示

2.若使用Winform的TreeNode 來達成需求 可能會遇上幾個難題

  • 無法得知節點所代表的資料
  • 每一個樹上的功能 都需要使用程序化的方式判斷節點類型 做出對應操作

3.使用物件導向的方式來解決以上的問題並達成需求

  • 首先,一個一般化的客製TreeNode
    // TModel 代表節點上所參考的資料
    class CustomNode<TModel> : TreeNode, IDoubleClick, INodeView<TModel> where TModel : DomainObjectBase
    {
        #region [JasonHuang  7/12/2010] Field
        private event EventHandler<EventArgs> _doubleClick;
        private string _member;
        private string _propertyName;
        #endregion

        #region [JasonHuang  7/12/2010] ctor
        public CustomNode()
        {
            NodePresenter<CustomNode<TModel>, TModel> presenter = new NodePresenter<CustomNode<TModel>, TModel>(this);
        }
        #endregion
  •  針對每一個功能,使用一個介面來代表,EX:雙擊開窗、改變節點顯示等...
   
 interface IDoubleClick    
 {        
      void DoubleClick();   
 }
  • 重構成MVP,將邏輯放在Presenter

 

    public class NodePresenter<TView, TModel>
        where TView : INodeView<TModel>
        where TModel : DomainObjectBase
    {
        IDialogService _dialogService;
        public NodePresenter(TView pView)
        {
            View = pView;
            //針對View介面的事件做處理
            View.DoubleClickView += new EventHandler<EventArgs>(OnDoubleClicView);
        }

        protected virtual void OnDoubleClicView(object sender, EventArgs e)
        {
            //功能 與 邏輯 在此
            IDialogService<TModel> service = DialogService as IDialogService<TModel>;
            if (service != null)
            {
                service.ShowDialog(View.Element);
            }
        }
  • 建造樹節點,可以使用泛型方法的方式

 

        internal static CustomNode<T> BuildNode<T>(T pItem, TreeNode pParentNode) where T : DomainObjectBase
        {
            CustomNode<T> node = null;
            node = new CustomNode<T>()
            {
                Element = pItem,
                PropertyName = DataModelQueryConst.DISPLAYNAME
            };
            pParentNode.Nodes.Add(node);
            return node;
        }

 

  •    使用方式,假設Client端要雙擊節點開窗 ,可以利用多型的方式
        private void browseTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            TreeNode node = e.Node;
            IDoubleClick doubleClick = node as IDoubleClick;
            doubleClick.SafeDoubleClick();
        }

4.利用物件導向的方式,可以去除許多if else 判斷,且能將責任分配到各物件中(SRP),往後就算樹節點所帶資料或操作改變,原始的程式碼也不用變更,只需要使用一般化的泛型樹節點或是實做特殊化的泛型樹節點即可。

 

分享