在Winform界面中實現對多文檔窗體的參數傳值


在Winform界面中窗體我們一般使用多文檔進行展示,也就是類似一般的選項卡的方式可以加載多個窗體界面。一般來說,我們如果打開新的窗體,給窗體傳遞參數是很容易的事情,但是在框架層面,一般的窗體是通過動態創建的,一般傳入窗體的類型,在多文檔集合里面判斷,如果存在則激活,如果不存在則創建的方式,所以我們傳遞參數會碰到一些問題。本文即使介紹如何在這種方式下,給窗體對象傳遞參數,從而實現相應的數據處理功能。

不管是主體界面中,左側包含樹形列表,還是頂部包含工具欄的情況,都可能涉及打開窗體的時候,傳遞一些初始化參數,方便窗體的更新顯示的情況,這種的處理相對直接傳值的方式需要復雜一點,我們可以通過接口、事件的方式進行處理,下面我來介紹一下整個實現的方式。

1、多文檔窗體的構建或者激活

在我的Winform開發框架里面,我們加載多文檔窗體的時候,都是統一采用一種方式來進行構建不存在或者激活已有窗體的,代碼如下所示。

        private void tool_Purchase_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            ChildWinManagement.LoadMdiForm(this, typeof(FrmPurchase));
        }

        private void tool_TakeOut_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            ChildWinManagement.LoadMdiForm(this, typeof(FrmTakeOut));
        }

        private void tool_StockSearch_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            ChildWinManagement.LoadMdiForm(this, typeof(FrmStockSearch));
        }

而這個LoadMdiForm的函數,主要判斷多文檔集合里面是否有對應的對象,沒有這創建,有則激活顯示即可,代碼如下所示。

        /// <summary>
        /// 唯一加載某個類型的窗體,如果存在則顯示,否則創建。
        /// </summary>
        /// <param name="mainDialog">主窗體對象</param>
        /// <param name="formType">待顯示的窗體類型</param>
        /// <param name="json">傳遞的參數內容,自定義Json格式</param>
        /// <returns></returns>
        public static Form LoadMdiForm(Form mainDialog, Type formType, string json)
        {
            bool bFound = false;
            Form tableForm = null;
            foreach (Form form in mainDialog.MdiChildren)
            {
                if (form.GetType() == formType)
                {
                    bFound = true;
                    tableForm = form;
                    break;
                }
            }
            if (!bFound)
            {
                tableForm = (Form) Activator.CreateInstance(formType);
                tableForm.MdiParent = mainDialog;
                tableForm.Show();
            }

            tableForm.BringToFront();
            tableForm.Activate();

            return tableForm;
        }

這種方式構建的多文檔界面如下所示。

 

2、多文檔窗體傳參數的實現處理

首先,為了實現這個方式,我們需要先創建一個接口,是我們窗體界面的基類,實現這個接口,然后在加載的時候,轉換為對應的接口處理就可以了,具體接口代碼如下所示。

    /// <summary>
    /// 使用ChildWinManagement輔助類處理多文檔加載的窗體,在構建或激活后,觸發一個通知窗體的事件,方便傳遞相關參數到目標窗體。
    /// 為了更加通用的處理,傳遞的參數使用JSON定義格式的字符串。
    /// </summary>
    public interface ILoadFormActived
    {
        /// <summary>
        /// 窗體激活的事件處理
        /// </summary>
        /// <param name="json">傳遞的參數內容,自定義JSON格式</param>
        void OnLoadFormActived(string json);
    }

這里參數為了通用,我們定義為字符串的JSON內容,方便實現更加強大的參數處理。

修改好這些,我們需要在基類窗體 BaseForm 實現這個增加的接口,如下所示。

    /// <summary>
    /// 常規界面基類
    /// </summary>
    public partial class BaseForm : XtraForm, IFunction, ILoadFormActived

實現這個接口很容易,為了更加方便業務窗體(繼承自基類窗體BaseForm),我們提供一個事件進行處理,具體代碼如下所示。

    /// <summary>
    /// 常規界面基類
    /// </summary>
    public partial class BaseForm : DevExpress.XtraEditors.XtraForm, IFunction, ILoadFormActived
    {
        /// <summary>
        /// 定義一個窗體激活后的處理委托類型
        /// </summary>
        /// <param name="json"></param>
        public delegate void FormActiveHandler(string json);
        /// <summary>
        /// 使用ChildWinManagement輔助類處理多文檔加載的窗體,在構建或激活后,觸發一個通知窗體的事件,方便傳遞相關參數到目標窗體。
        /// 為了更加通用的處理,傳遞的參數使用JSON定義格式的字符串。
        /// </summary>
        public event FormActiveHandler LoadFormActived;

同時,我們實現接口,就是直接調用事件就可以了,具體代碼如下所示。

        /// <summary>
        /// 窗體激活的事件處理
        /// </summary>
        /// <param name="json">傳遞的參數內容,自定義JSON格式</param>
        public virtual void OnLoadFormActived(string json)
        {
            //默認什么也沒做
            //如果需要處理傳參數,則在這里處理參數Json即可
            if (LoadFormActived != null)
            {
                LoadFormActived(json);
            }
        }

這樣我們就完成了基類窗體的處理了,前面我們介紹了動態構建加載窗體的時候,是使用了LoadMdiForm的函數,既然我們的接口實現了上面的ILoadFormActived接口,那么我們動態創建或者激活窗體的時候,那么就使用這個接口進行處理一下,以便實現對應事件的處理操作了。因此我們的窗體加載函數修改代碼,如下所示。

        /// <summary>
        /// 唯一加載某個類型的窗體,如果存在則顯示,否則創建。
        /// </summary>
        /// <param name="mainDialog">主窗體對象</param>
        /// <param name="formType">待顯示的窗體類型</param>
        /// <param name="json">傳遞的參數內容,自定義Json格式</param>
        /// <returns></returns>
        public static Form LoadMdiForm(Form mainDialog, Type formType, string json)
        {
            bool bFound = false;
            Form tableForm = null;
            foreach (Form form in mainDialog.MdiChildren)
            {
                if (form.GetType() == formType)
                {
                    bFound = true;
                    tableForm = form;
                    break;
                }
            }
            if (!bFound)
            {
                tableForm = (Form) Activator.CreateInstance(formType);
                tableForm.MdiParent = mainDialog;
                tableForm.Show();
            }

            //窗體激活的時候,傳遞對應的參數信息
            ILoadFormActived formActived = tableForm as ILoadFormActived;
            if (formActived != null) { formActived.OnLoadFormActived(json); }

            tableForm.BringToFront();
            tableForm.Activate();

            return tableForm;
        }

還記得我們前面打開一個多文檔窗體的代碼,就是利用這個接口進行創建或者激活指定類型的窗體的,如下所示。

ChildWinManagement.LoadMdiForm(this, typeof(FrmItemDetail));

那么我們增加了新的函數參數Json后,我們如果需要傳遞一個指定的參數給對應的窗體,那么就修改下調用即可。例如下面,為了測試,我傳入一個動態構建的類信息,然后轉換為Json字符串信息給接收窗體,並進行加載窗體。

            //使用自定義參數調用
            var obj = new { ItemNo = "123456789", ItemName = "測試名稱" };
            var param = JsonConvert.SerializeObject(obj, Formatting.Indented);

            ChildWinManagement.LoadMdiForm(this, typeof(FrmItemDetail), param);

前面我們介紹了基類窗體,已經實現定義了一個事件,並對這些通知的接口進行處理,具體如下所示。

那么我們前面加載的 FrmItemDetail  需要做哪些工作呢,就是實現對事件的處理即可,如下所示。

這樣我們就能夠通過實現對應的事件,把整個通知事件的處理處理完畢了,我們來看看最終的界面效果,如下所示,接收到的窗體事件后,會彈出一個提示對話框在右下角了。

當然實際上我們可以做的更多,如可以傳遞一些具體的信息,讓它在界面上進行顯示。

如其中一個客戶基於我的Winform開發框架基礎上進行的參數傳遞案例界面如下所示。

本文只是對其中在框架層面對不同多文檔窗體的傳值進行的一個研究探索和實現,其中的理念是基於常用的接口和事件驅動的方式進行處理,以期達到方便、高效的目的,如果您有更好的建議,也希望多多交流。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM