摘要:客製化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),往後就算樹節點所帶資料或操作改變,原始的程式碼也不用變更,只需要使用一般化的泛型樹節點或是實做特殊化的泛型樹節點即可。