我有一个表单和另一个类文件,当我单击主窗体中的一个按钮时,它将一个值传递给另一个文件中另一个类中的函数(此函数是通用的,由所有文件调用),它再次调用主表单/类中的函数并更新文本框。
我编写了代码,但它抛出异常,说“在创建窗口句柄之前,无法在控件上调用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;
}
}
}
答案 0 :(得分:1)
您需要将Form1
的引用传递给nnn()
:
c1.nnn(this, a);
...
public int nnn(Form1 theMDIform, int a)
{
...
}
并从Form1 theMDIform
类中删除Class1
成员。
目前,您从nnn()
对象调用Form1
,但之后又回拨了另一个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){ ...}
}
答案 1 :(得分:0)
为了避免紧张coupling,我建议不要使用parctices,例如将表单作为参数传递(如果必须,请使用符合DIP原则的界面),或者制作Class1
从您的表单中“请求”操作。
我的建议是以主从方式设计你的程序。你的class1
(伪装成奴隶)应该做它做的事情,并告诉谁想知道它使用事件的动作。你的奴隶班不应该知道你的更高级别的大师班的存在(你的形式是AKA)
表单将监听事件,并采取您认为适合触发事件的操作。
在底线,这并不是你现在所做的大改变。主要区别在于应删除事件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;
}