问题描述
我正在开发客户端/服务器应用程序。 在客户端应用程序中,我有一个主窗体,该主窗体是MDI父级。 主窗体具有一个Load事件,该事件创建一个子窗体的新实例并使它可见。 此事件还将Main设置为Child的MdiParent。 子窗体旨在作为登录屏幕。 从子窗体中,我创建了对父窗体的引用,以便能够从父窗体调用方法。
但是,在执行MdiParent.RequestConnection方法时,GUI被卡住了。 因此,我尝试从线程执行该方法,但是即使我似乎遵循正确的语法,它也不接受我的声明。 我看不到我在做什么错。请帮忙
主要形式
public partial class frmMainForm: Form
{
public frmMainForm()
{
InitializeComponent();
}
Thread runningClient;
public MyTcpClient client= new MyTcpClient ();
frmChildForm frmSignIn;
bool clientConnected;
private void frmMainForm_Load(object sender,EventArgs e)
{
clientConnected= false;
panelSidebar.Hide();
if(frmSignIn == null)
{
frmSignIn= new frmChildForm();
frmSignIn.MdiParent = this;
frmSignIn.Show();
}
}
public void TurnOnPanels()
{
panelSidebar.Visible = true;
panelSidebar.BringToFront();
}
public void RequestConnection(string username)
{
string serverRsp = client.Connect(username);
if(serverRsp.Equals("SUCCESS"))
{
MessageBox.Show("Signed In","Welcome",MessageBoxButtons.OK,MessageBoxIcon.Information);
clientConnected = true;
frmSignIn.Close();
}
}
}
还有我的孩子表格
public partial class frmChildForm : Form
{
frmMainForm frmParent;
Thread clientRunning;
public frmChildForm()
{
InitializeComponent();
frmParent= (frmMainForm)this.MdiParent;
}
private void frmSignIn_FormClosing(object sender,FormClosingEventArgs e)
{
frmParent= (frmMainForm)this.MdiParent;
frmParent.TurnOnPanels();
}
private void btnSignIn_Click(object sender,EventArgs e)
{
if (txtSignInUsername.Text.Equals(""))
{
MessageBox.Show("No empty fields.","Error",MessageBoxIcon.Error);
}
else
{
//This is where it fails
clientRunning= new Thread(new ParameterizedThreadStart(frmParent.RequestConnection);
//"No Overload for RequestConnection matches delegate ParameterizedThreadStart"
//If I try to include the parameter inside that call,I get a "waiting for method //name" syntax error message instead.
clientRunning.Start(txtSignInUsername.Text.ToUpper());
}
}
private void frmSignIn_Load(object sender,EventArgs e)
{
frmParent = (frmMainForm)this.MdiParent;
}
}
我还尝试通过在RequestConnection内创建一个线程来从主表单执行此操作,该线程应在该线程上执行client.Connect,但我遇到了相同的错误。
解决方法
您需要修复的事物
public void RequestConnection(object username) // changed parameter type
{
if (username == null)
throw new ArgumentNullException(nameof(username));
if (!(username is string))
throw new InvalidCastException("Expect string");// give proper message
string serverRsp = client.Connect(username.ToString());
if (serverRsp.Equals("SUCCESS"))
{
MessageBox.Show("Signed In","Welcome",MessageBoxButtons.OK,MessageBoxIcon.Information);
clientConnected = true;
//this is require to solve cross-thread operation
if (this.InvokeRequired)
this.Invoke(new MethodInvoker(delegate ()
{
frmSignIn.Close();
}));
else
frmSignIn.Close();
}
}
您需要在“表单加载事件”中获取MdiParent并从构造函数中删除。
您的子表单加载事件/或使用父项更改事件
private void FrmLogin_Load(object sender,EventArgs e)
{
frmParent = (MainForm)this.MdiParent;
}
,
ParametrizedThreadStart委托实际上将一个对象作为参数。
因此,您必须为它提供一个将对象作为参数而不是字符串的方法。在您的方法中,您将收到对象,检查它是否为字符串,然后将其转换为字符串。