我在面板中有一个按钮,它将调用另一个方法,该方法将创建一个用户控件来覆盖整个面板。这是面板按钮单击事件的代码:
private void btnTarget_Click(object sender, EventArgs e)
{
UtilLoader.ShowLoader(this);
lblStatus.Text = "Done";
}
ShowLoader的代码是这样的:
internal class UtilLoader
{
public static void ShowLoader(Control parent)
{
var ct = new UcLoaderBox(parent)
{
Dock = DockStyle.Fill,
Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right,
Bounds = parent.ClientRectangle
};
parent.Controls.Add(ct);
ct.BringToFront();
ct.SubmitMessage += (sender, args) => { /* Here I can detect if user control is closed */ };
}
}
用户控件有一个名为的事件SubmitMessage
如果用户单击用户控件内的按钮,则会触发该事件。这btnTarget_Click
将打开用户控件,然后立即执行lblStatus.Text = "Done;
我需要等待SubmitMessage
在用户控件内触发。
我尝试使用做这样的事情ManualResetEvent
,但没有成功,它不会停止等待:
internal class UtilLoader
{
public static async void ShowLoader(Control parent)
{
var waiter = new ManualResetEvent(false);
var ct = new UcLoaderBox(parent)
{
Dock = DockStyle.Fill,
Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right,
Bounds = parent.ClientRectangle
};
parent.Controls.Add(ct);
ct.BringToFront();
ct.SubmitMessage += (sender, args) => { waiter.Reset(); };
await Task.Run(()=> waiter.WaitOne());
}
}
我还使用了下面的代码并替换await ct.WhenClicked
代替await Task.Run(()=> waiter.WaitOne());
在上面的代码中,但仍然没有等待!
public static class Utils
{
public static Task WhenClicked(this Control target)
{
var tcs = new TaskCompletionSource<object>();
EventHandler onClick = null;
onClick = (sender, e) =>
{
((UcLoaderBox) target).SubmitMessage -= onClick;
tcs.TrySetResult(null);
};
((UcLoaderBox)target).SubmitMessage += onClick;
return tcs.Task;
}
}
我应该做什么来实现我的目标?
Updated:
有了安迪的答案,现在就可以正常工作了。但还有另一个问题。
该用户控件充当模态框,它会在需要时出现。我正在添加它并用旧的消息框系统替换它。该按钮可以调用插入数据库的方法或登录文本文件的另一个方法。在这些方法中,用户控件可以在其父控件上显示为模式。
我可以将父参数添加到这些方法中,并将父控件传递给它们,这样每当它们想要显示模式时,它们就可以,如果没有,则什么也没有。
但是将所有这些方法转换为 async-await 并将所有按钮事件转换为 async-await 非常困难。