[英]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.