我在从其他线程处理表单时遇到问题。
我通过在运行时加载表单,显示它然后隐藏它来克服了这个问题。这意味着表单是在正确的线程上创建的,可以使用调用进行操作。
这不是正确的方法。我有3个问题来自使用此方法
如果有人能指出我正确的方向,我将不胜感激。目前我的代码如下:
在主表单上加载:
CallerIDfrm = new frmCallerID();
CallerIDfrm.Show();
CallerIDfrm.Hide();
使用
操作弹出窗口Im delegate void StringArgReturningVoidDelegate1(string CallerIDnum, string CallerIDname, string ContactID);
private void CallerID(string CallerIDnum, string CallerIDname, string ContactID)
{
if (CallerIDfrm.InvokeRequired)
{
StringArgReturningVoidDelegate1 d = new StringArgReturningVoidDelegate1(CallerID);
CallerIDfrm.Invoke(d, new object[] { CallerIDnum, CallerIDname, ContactID });
}
else
{
if (ContactID != null || ContactID != "0")
{
CallerIDfrm.ContactID = ContactID;
}
CallerIDfrm.Mainfrm = this;
CallerIDfrm.TopLevel = true;
CallerIDfrm.TopMost = true;
CallerIDfrm.lblCallerIDname.Text = CallerIDname;
CallerIDfrm.lblCallerIDnum.Text = CallerIDnum;
CallerIDfrm.Show();
CallerIDOpen = true;
}
}
使用以下方法隐藏弹出窗口,直到需要:
delegate void StringArgReturningVoidDelegate2();
private void CallerIDClose()
{
if (CallerIDfrm.InvokeRequired)
{
StringArgReturningVoidDelegate2 d = new StringArgReturningVoidDelegate2(CallerIDClose);
CallerIDfrm.Invoke(d, new object[] { });
}
else
{
try
{
CallerIDfrm.Hide();
CallerIDOpen = false;
}
catch
{
}
}
}
我已经尝试了其他方法,但Popup加载就好像它没有响应而且我无法访问弹出窗口。
最终,我希望能够生成多个弹出窗口,并能够从主窗体中关闭它们。
答案 0 :(得分:0)
我从你的问题中收集到的内容:你有一个来电者api / lib / class,你喜欢在收到电话时在弹出窗体上显示CallerId。看看Events and Event Driven programming。
以下代码尚未经过测试,我是从头顶编写的。可能无法编译,他们在这里展示一个例子:
在api / lib类中创建一个CallReceived事件,如下所示:
public event EventHandler<CallReceivedEventArgs> CallReceived;
protected void OnCallReceived(EventArgs e)
{
var handler = CallReceived;
if (handler != null)
handler(this, e);
// Note: For C# 6.0 and later, above statements can be simplified to
// CallReceived?.Invoke(this, e);
}
注意:如果您无法访问此api / lib代码,请创建一个Gateway类并将您的事件放在那里以及触发它的机制。
还创建一个CallReceivedEventArgs,这将用于传输事件数据:
public class CallReceivedEventArgs : EventArgs
{
public string CallerIDnum {get; set;}
public string CallerIDname {get; set;}
public string ContactID {get; set;}
}
现在,在你的api / lib类中,只要收到一个电话就会引发这个事件:
// a call received, replace dummy values with actual values
OnCallReceived(new CallReceivedEventArgs() { CallerIDnum="5554443322", CallerIDname="SOME_NAME", ContactID="SOME_CONTACT" });
最后在您的GUI表单中,注册所述事件并相应地处理。
// inside your main form class
private CallerAPI callerApi = new CallerAPI();
// somewhere inside you main form class, register to event
// from your use case, I would place it inside Main Form's constructor
callerApi.CallReceived += callerApi_Callreceived;
// receive event
void callerApi_Callreceived(object sender, CallReceivedEventArgs e)
{
var callerIDnum = e.CallerIDnum;
// etc.
// show callerId form with details
// you need to change frmCallerID's constructor accordingly
CallerIDfrm = new frmCallerID(e.CallerIDnum, CallerIDname, ContantID);
// to be able to track opened popups, you can store them inside a list
// private List<Form> openPopupList = new List<Form>();
//
// alternatively, you can assign CallerIDnum to form's name property
// and store these inside a List<string> instead of List<Form>
openPopupList.add(CallerIDfrm);
CallerIDfrm.Show();
}
不要忘记从事件中取消注册。
callerApi.CallReceived -= callerApi_Callreceived;
包装起来:
- 我无法生成另一个弹出框我必须使用我在运行时创建的弹出框
醇>
您可以创建并显示多个frmCallerID,彼此独立。
- 这些表格在加载时会短暂闪现 - 现在我有3种形式,这显然是我正在做的事情。
醇>
由于新方法基于事件创建了CallerID表单,因此您不会看到这些表单闪烁。只要收到CallReceived事件,它就会打开。
- 如果弹出窗口是打开的话,我必须使用变量bool来保持。
醇>
更好的方法是:注册表格FormClosed事件,并相应地从openPopupList
删除。
frmCallerID.FormClosed += frmCallerID_FormClosed;
void frmCallerID_FormClosed(object sender, EventArgs e)
{
// remove form from openPopupList
frmCallerID closedPopup = (frmCallerID) sender;
openPopupList.remove(closedPopup);
}