C# 經過委託實現兩個程序集間的雙向調用

這個問題是我在今天的工做中遇到的。有兩個C#程序集,主程序集的窗口甲要調用副程序集的窗口乙,主程序集引用了副程序集。如今的問題是,窗口甲打開窗口乙後,除要實現窗口甲調用窗口乙的內容外,窗口乙也須要調用窗口甲的功能。ide

如今主程序集引用了副程序集,天然能夠實現窗口甲調用窗口乙內的功能。但副程序集已經不能再引用主程序集,由於這樣會形成循環依賴的狀況,這是VS所不容許的。測試

通過一番研究,我發現使用委託能夠很容易地完成上述功能。現將DEMO程序講解以下:ui

其中AssemblyTest1就是上面說的程序集甲,AssemblyTest2是程序集乙。AssemblyTest1引用了AssemblyTest2。this

FormMain是程序集AssemblyTest1的主窗體,裏面只有一個按鈕,功能是打開AssemblyTest2的主窗體FormTest。spa

FormMain的代碼以下:code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AssemblyTest1
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }

        AssemblyTest2.FormTest formTest = new AssemblyTest2.FormTest();

        private void FormMain_Load(object sender, EventArgs e)
        {
            formTest = new AssemblyTest2.FormTest();
            formTest.GeneratePoem += (obj, poem) =>
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine(poem.title + "," + poem.author);
                    sb.AppendLine(poem.sentence1 + ",");
                    sb.AppendLine(poem.sentence2 + "。");
                    sb.AppendLine(poem.sentence3 + ",");
                    sb.AppendLine(poem.sentence4 + "。");
                    MessageBox.Show(sb.ToString());
                };
        }

        private void btnOpenFormTest_Click(object sender, EventArgs e)
        {
            formTest.InitPoem(
                "江雪", "柳宗元", 
                "千山鳥飛絕",
                "萬徑人蹤滅",
                "孤舟蓑笠翁", 
                "獨釣寒江雪");
            formTest.Show();
        }
    }
}

FormTest是被FormMain中按鈕打開的窗體,它位於AssemblyTest2程序集內。爲了實現調用FormMain的功能,我將邏輯實如今了FormMain中(即formTest.GeneratePoem後面的那個Lambda表達式)。orm

FormTest代碼以下:事件

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AssemblyTest2
{
    public partial class FormTest : Form
    {
        public FormTest()
        {
            InitializeComponent();
        }

        public void InitPoem(string title, string author, 
            string s1, string s2, string s3, string s4)
        {
            this.txtTitle.Text = title;
            this.txtAuthor.Text = author;
            this.txtSentence1.Text = s1;
            this.txtSentence2.Text = s2;
            this.txtSentence3.Text = s3;
            this.txtSentence4.Text = s4;
        }

        /// <summary>
        /// 定義委託類
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="data"></param>
        public delegate void AssemblyTestCustomHandle(object sender, Poem poem);
        /// <summary>
        /// 獲取古詩內容
        /// </summary>
        public event AssemblyTestCustomHandle GeneratePoem;

        /// <summary>
        /// 生成古詩內容 - FormMain訂閱了該事件後便可獲取
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnNotifyFormMain_Click(object sender, EventArgs e)
        {
            if (GeneratePoem != null)
            {
                Poem poem = new Poem();
                poem.title = this.txtTitle.Text;
                poem.author = this.txtAuthor.Text;
                poem.sentence1 = this.txtSentence1.Text;
                poem.sentence2 = this.txtSentence2.Text;
                poem.sentence3 = this.txtSentence3.Text;
                poem.sentence4 = this.txtSentence4.Text;
                GeneratePoem(this, poem);
            }
        }

        private void FormTest_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            this.Hide();
        }
    }
}

點擊按鈕btnNotifyFormMain後,會進入事件GeneratePoem,而這個事件是在FormMain中實現的,這等於變相調用了FormMain中的邏輯,FormMain中實現的邏輯天然也能夠調用FormMain窗體中的一些全局變量等內容。string

程序運行效果圖以下:it

一、在FormMain中點擊「打開測試窗體」按鈕,彈出「被調用窗體」FormTest

二、在「被調用窗體」中點擊「調用主窗體邏輯」按鈕後,「被調用窗體」中的各項參數此時被傳遞到主窗體,並由主窗體按自身邏輯拼接成串,經過MessageBox予以輸出。

END

相關文章
相關標籤/搜索