在我的应用程序中,我使用子表单,用户必须将一些数据填入文本框,然后单击“确定”或“取消”。为了防止使用空字段,我想使用一个后台工作程序来监视字段并保持“确定”按钮被禁用,直到填满所有字段。代码(几乎)工作但在子窗体处理时抛出异常,可能是因为bgw仍在运行但表单已经处理掉了。我怎样才能正确阻止bgw?
private void FormRecSettings_Load(object sender, EventArgs e)
{
this.tb_recdatetime.Text = DateTime.Today.ToString("yyyyMMdd") + "_";
backgroundWorker2.WorkerSupportsCancellation = true;
backgroundWorker2.DoWork += new DoWorkEventHandler(backgroundWorker2_DoWork);
btn_ok.Enabled = false;
if (backgroundWorker2.IsBusy != true)
{
backgroundWorker2.RunWorkerAsync();
}
}
void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
while(true)
{
if ((backgroundWorker2.CancellationPending == true))
{
e.Cancel = true;
}
if (tb_recsuffix.Text.Length > 0 && tb_filename.Text.Length > 0)
SetControlPropertyThreadSafe(btn_ok, "Enabled", true);
else SetControlPropertyThreadSafe(btn_ok, "Enabled", false);
}
}
public static void SetControlPropertyThreadSafe(Control control, string propertyName, object propertyValue)
{
if (control.InvokeRequired)
{
control.Invoke(new SetControlPropertyThreadSafeDelegate(SetControlPropertyThreadSafe), new object[] { control, propertyName, propertyValue });
}
else
{
control.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, control, new object[] { propertyValue });
}
}
private void btn_ok_Click(object sender, EventArgs e)
{
if (backgroundWorker2.WorkerSupportsCancellation == true)
{
backgroundWorker2.CancelAsync();
}
string mm, inv;
if (rbtn_UK.Checked == true) mm = "UK";
else mm = "DE";
if (rbtn_invyes.Checked == true) inv = "Yes";
else inv = "No";
// instance the event args and pass it each value
NewRecUpdateEventArgs args = new NewRecUpdateEventArgs(tb_recsuffix.Text, tb_filename.Text, mm,
inv);
// raise the event with the updated arguments
NewRecUpdated(this, args);
this.Dispose();
}
答案 0 :(得分:1)
很抱歉地说,但在我看来,BackgroundWorker
有点矫枉过正,可能会给你带来更多问题,然后快乐。
我建议连接TextChanged
的{{1}}事件并检查是否可以启用按钮。
TextBox
事件处理程序:
foreach (Control c in this.Controls)
{
if (c is TextBox)
{
c.TextChanged += tb_TextChanged;
}
}
答案 1 :(得分:0)
根据Patrick的提示更新了我的doWork功能,现在看起来工作正常(见下文)。但是,Patrick的基于事件的textchanged解决方案更好。
void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
if ((backgroundWorker2.CancellationPending == true))
{
e.Cancel = true;
}
if (!this.IsDisposed || this.Disposing)
{
if (tb_recsuffix.Text.Length > 0 && tb_filename.Text.Length > 0)
SetControlPropertyThreadSafe(btn_ok, "Enabled", true);
else SetControlPropertyThreadSafe(btn_ok, "Enabled", false);
}
Thread.Sleep(500);
}
}