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