程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 控件使用經驗-MVP模式+控件封裝,控件-mvp

控件使用經驗-MVP模式+控件封裝,控件-mvp

編輯:關於.NET

控件使用經驗-MVP模式+控件封裝,控件-mvp


項目背景

幾年前參與了一個面向學校的人事管理軟件的開發,基於WinForm平台。今天主要想談一談其中關於控件的使用經驗。這個項目我們大量使用了第三方控件。由於這個產品的生命周期很長,我們在設計時要考慮表現層可能會有不同的形式,比如現在是WinForm以後可能會是WPF或者Web。另外也要考慮控件版本升級對產品的影響降到最低。

設計

基於上面的想法,我們通過兩點來解決這些問題。MVP模式+控件封裝,可以開發出更具彈性的View層。它能更有效的應對UI變化,包括控件升級這種小的UI變化,甚至是平台遷移等這種大的UI變化。

MVP(Model-View-Presenter)模式主要是為了表現層解耦,如果表現層的職責不單一,那麼有控件升級或者UI層使用新的平台時花費的成本就會很高。使用MVC之後只有View層和控件相關,Presenter層實現UI邏輯。當View層變化時(控件升級或者新的UI形式),Presenter層、Model層都會被重用。

控件封裝可以以一種統一的方式使用控件。所有使用到的控件全部封裝即使是.Net控件也進行封裝,不允許使用任何原生控件,只能使用封裝後的控件。我們對控件的進行深度封裝,將很多功能在控件中實現。

控件封裝經驗

我們以表格功能為例來介紹我們如何進行控件封裝。在我們項目中對表格功能的要求非常高,一方面功能要非常強大,而且具有很強的定制開發能力,另一方面要求表格控件具有良好的性能。下面通過幾個UI了解我們對表格的要求。

 

圖1

 

 

圖2

 

圖3

圖1和圖2展示的是職員一覽畫面中,我們不僅僅加載出了職員信息,而且加載了職員的照片,需要一次性從數據庫中加載幾千張職員照片,對表格的性能要求很高。

圖3展示以時間軸方式顯示的職員狀態。點擊放大、縮小按鈕,時間刻度的粒度也會發生變化,並重新刷新數據。

通過以上的兩個示例可以看出我們對表格的性能和擴展性要求很高。我們綜合對比了Spread,FlexGrid,MutilRow這幾種表格控件,最終我們選擇了葡萄城公司的Component產品中的FlexGrid控件。

FlexGrid控件封裝

圖4

圖4是我們基於FlexGrid進行了深度封裝的類圖。在項目中不允許直接使用FlexGrid,只能使用我們封裝後的JijiEditGrid等控件。我們以JijiBaseGrid為例來看看我們是如何進行封裝。

 

下面節選了我們JijBaseGrid中的一些功能。

功能

描述

處理

Option機制

記憶列寬、字段順序等

方法:LoadOption、SaveOption

列頭菜單

字段顯示/隱藏

屬性:NeedHeaderMenu(設計時不可用)

統一管理顏色

Grid的配色是否隨著Form走

屬性:IsColorManaged(設計時可用)

接口:IColorControl

拷貝到剪貼板

根據Option進行特殊處理,分隔符、日期格式等

方法:CopyGridRangeToClip(RealText realText)

事件:public event EventHandler DataCopy = delegate { };

特殊鍵

F9:自動調整列寬

Ctrl+A:全選

Ctrl+C:復制

Delete:刪除

PageDown:數據不滿一頁,PageDown按下時,跳轉到最後一行

事件處理函數:override void OnKeyDown

 

我們僅僅選擇“特殊鍵”這個功能,看看在OnKeyDown中的處理。這裡主要處理各種特殊按鈕,比如F9等。

        /// <summary>
        /// Grid的按鍵押下事件
        /// </summary>
        /// <param name="e">參數</param>
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);

            // 記錄Control鍵是否按下
            this.controlDown = e.Control;

            switch (e.KeyCode)
            {
                case Keys.F9:
                    if (this.CanF9)
                    {
                        // 列寬自動調整
                        Color oldColor = this.BackColor;
                        this.AutoSizeCols();
                        this.BackColor = oldColor;
                    }
                    break;

                case Keys.Delete:
                    if (this.CanDeleteRow())
                    {
                        // 處理行刪除事件
                        this.RowDelete(this, new EventArgs());
                    }
                    else if (this.CanDeleteCellRange())
                    {
                        // 處理Cell范圍選中刪除事件
                        this.CellRangeDelete(this, new EventArgs());
                    }
                    break;

                case Keys.A:
                    if (e.Control)
                    {
                        // ctrl + A鍵的操作(全選)
                        int rowCount = this.GetRowCount();
                        if (rowCount > this.Rows.Fixed)
                        {
                            this.isControlA = true;

                            this.Select(this.Rows.Fixed, this.Cols.Fixed, false);
                            this.Select(this.Rows.Fixed, this.Cols.Fixed, rowCount, this.Cols.Count - 1, false);

                            this.isControlA = false;
                        }
                    }
                    break;

                case Keys.C:
                    if (e.Control && this.AllowCopy && this.DataCopy != null && this.DataCopy.Target != null)
                    {
                        // ctrl + C鍵的操作(復制)
                        this.DataCopy(this, new EventArgs());
                    }
                    break;

                case Keys.PageDown:
                    // 特殊處理數據不滿一頁,PageDown按下時,跳轉到最後一行
                    this.DoPageDownEvent();
                    break;
            }
        }

 

默認的FlexGrid是沒有這些功能的,我們重寫OnKeyDown方法。根據自己的需求增加對各種特殊鍵的處理。

通過對控件進行全面的封裝,當有新的需求或者有需求變更時和控件相關的功能我們只需在封裝的控件中進行修改即可。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved