我有两个表单和一个单例类。我正在使用formA的btn_A_Click中的单例类。
public partial class frmA : Form
{
public frmA()
{
InitializeComponent();
frmB frmB;
}
private void btn_A_Click(object sender, EventArgs e)
{
SessionMgmt.GetInstance().StartFormB();
}
}
这是我的单例类,在这里我尝试使用Forms.Invoke()方法。
public class SessionMgmt
{
static SessionMgmt _sessinMgr;
frmB frB;
private SessionMgmt()
{
frB = new frmB();
}
public static SessionMgmt GetInstance()
{
if (_sessinMgr != null)
return _sessinMgr;
else
{
_sessinMgr = new SessionMgmt();
return _sessinMgr;
}
}
public bool StartFormB()
{
frB.Invoke(new EventHandler(DisplayFrmB));
return true;
}
private void DisplayFrmB(Object o, EventArgs e)
{
frB.Visible = true;
frB.Refresh();
}
}
这是我的表格。
public partial class frmB : Form
{
}
但是从frB.Invoke(new EventHandler(DisplayFrmB));
方法引发了以下异常:
在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke。
我无法弄清楚这个问题,如果我遗漏了任何内容,请提供帮助或建议。
修改
以下结构是我当前项目显示下一个表单的方式。它是由VB.NET完成的,我需要在使用C#的新项目中使用类似的东西。我看到了Invoke函数,它指向一个事件,然后指向一个函数。在该函数中,它只使Form.Visible = true和Form.Refresh。但是为了理解我只是尝试了一个POc并遵循相同的步骤,但它还没有解决。
答案 0 :(得分:2)
调用invoke的原因是什么?这不是为你做的工作吗?
public bool StartFormB()
{
frB.Visible = true;
return true;
}
答案 1 :(得分:0)
Windows窗体是Windows API的包装器,该异常意味着尚未创建基础窗口。我认为第一次将Visible
设置为true
时会创建它,还有其他几种情况可以实现。
请参阅此链接以获取可能的解决方案:http://blogs.msdn.com/b/mapo/archive/2011/04/27/forcing-handle-creation-in-a-net-windows-forms-control.aspx
答案 2 :(得分:0)
该异常有两个可能的原因:
你应该在调用之前检查InvokeRequired
属性,当然在那之前检查是否为
public bool StartFormB()
{
if (frB == null)
{
throw new ArgumentNullException("frB");
}
if (frB.InvokeRequired)
{
frB.Invoke(new EventHandler(DisplayFrmB));
}
else
{
if (frB.IsDisposed)
{
throw new ObjectDisposedException("Control is already disposed.");
}
}
return true;
}
答案 3 :(得分:0)
如果控件的Visible属性为false,则不会创建控件句柄。当您调用Invoke时,您在委托中将控件可见状态设置为true,但尚未创建句柄,因此您无法调用Invoke。所以 - 你必须调用frB.CreateHandle(); after:frB = new frmB();强制创建控制句柄
private SessionMgmt()
{
frB = new frmB();
var h = frB.Handle;
}