簡體   English   中英

使用委托從另一個類調用主類函數

[英]call a main class function from another class using delegates

我有一個窗體和另一個類文件,當我單擊主窗體中的按鈕時,它將值傳遞給另一個文件中另一個類中的函數(此函數是通用的,被所有文件調用),然后再次調用主窗體/類和更新文本框。

我已經編寫了代碼,但是拋出了異常,提示“在創建窗口句柄之前,無法在控件上調用Invoke或BeginInvoke”。

代碼在這里.. plz正確的地方是錯誤的。 主窗體有一個按鈕和一個文本框。

主要形式

namespace One
{
public partial class Form1 : Form
{
    public delegate void WriteToListBoxDelegate(string StringForText);

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Class1 c1 = new Class1();
        int a = 9;

        c1.nnn(a);            
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }
    public void SetListBox(string StringForText)
    {
        textBox1.Text += DateTime.UtcNow.ToString("dd-MM-yyyy HH:mm:ss") + ": " + StringForText + '\n' + textBox1.Text;
        MessageBox.Show(textBox1.Text);            
    }

}
}

另一個類文件

namespace One
{
public  class Class1
{   
    public One.Form1 theMDIform = new One.Form1();

    public int nnn(int a)
    {

        theMDIform.Invoke(new Form1.WriteToListBoxDelegate(theMDIform.SetListBox), '1');
    return 0;
    }
}
}

您需要將對Form1的引用傳遞給nnn()

c1.nnn(this, a);
...
public int nnn(Form1 theMDIform, int a)
{
    ...
}

並從Class1類中刪除Form1 theMDIform成員。

目前,您從Form1對象調用nnn() ,但隨后又調用了另一個不正確的Form1對象。 您需要回調相同的Form1對象。

加成
當您從其他形式調用nnn()時,您還需要傳遞對Form1的引用。 因此,您需要其他形式才能以某種方式獲取該引用。 一種可能的解決方案是將對Form1的引用存儲在靜態變量中。 那將是Singleton模式的實現。 我個人不喜歡這種方法,因為您將來可能會決定擁有多個Form1對象:

class Form1{
    private static Form1 oInstance;

    // Don't call it from the `Form1` constructor because that
    // will publish the not completely constructed object!
    private void InitInstance(){
        if (oInstance == null)
            oInstance = this;
        else
            throw new SomeException(...);
    }

    public Form1 Instance{
        get{ return oInstance;}
    }
    ...
};

然后其他表單可以獲取所需的引用作為Form1.Instance並將其傳遞給nnn()

但是我更希望將對Form1對象的引用傳遞給每個表單,例如作為構造函數參數:

class OtherForm{
    private Form1 MainForm;

    public OtherForm(Form1 MainForm){ ...}
}

為了避免緊密耦合 ,我建議不要使用諸如將您的表單作為參數傳遞的語句(如果必須,請遵循DIP原則使用接口),或使Class1從表單中“請求”操作。

我建議的是以主從方式設計程序。 您的class1 (冒充為奴隸)應該執行其操作,並使用事件通知想要知道其操作的人員。 您的奴隸班級應該不知道您的高級碩士班級的存在(也就是您的表格)

該表單將偵聽該事件,並采取您認為適合觸發事件的操作。

最重要的是,這與您目前所擁有的沒有太大的變化。 主要區別在於應該刪除事件WriteToListBoxDelegate ,而不是將onNnn事件添加到class1並使您的窗體偵聽該事件。

該事件的代碼如下所示:

public event EventHandler<StringArgs> onNnn;
public int nnn(int a)
{

    if(this.onNnn != null)
    {
        string s = "any text you want to path";
        StringArgs arg = new StringArgs(s);
        this.onNnn(this,arg);
    }
    return 0;
}

StringArgs的聲明:

public class StringArgs : EventArgs
{
    private readonly string _txt;
    public string Txt
    {
        get { return this._txt; }
    }

    public StringArgs (string txt)
    {
        this._txt = txt;
    }   
}

並在表單中添加綁定到事件:

public Form1()
{
    InitializeComponent();
    class1Instance.onNnnn += this.HandleClass1Nnn;

}

private voit HandleClass1Nnn(object sender, StringArgs args)
{
     textBox1.Text += args.Txt;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM