例如,我的Windows窗体上有2个命令按钮和一个文本框 单击命令按钮1,文本框值继续增加,例如从1到1000000.
发生这种情况时,我无法点击表单上的任何位置,包括命令按钮2 只有当计数器停在1000000时,我才能再次访问该表格。
请就此提出建议。
我还尝试使用*.Show();
方法使用无模型表单。
这是我在TextBox中获取值的代码。
for (int i = 0; i <= 10000; i++)
{
Console.WriteLine(i);
this.textBox1.Text = Convert.ToString(i);
label2.Focus();
this.textBox1.Focus();
}
答案 0 :(得分:0)
原因是您正在执行一项任务,需要一些时间才能完成,在您想要引发事件的同一个线程中(即单击按钮)。在单个线程中,所有任务都以一系列方式完成(一次一个)。换句话说,如果一个任务完成,那么另一个任务就要开始了。
为此,您需要在另一个线程(而不是主线程)中运行此任务。我希望这个DotNet Perls Link 帮助你。
答案 1 :(得分:0)
为了从不同的线程与UI进行交互,您需要使用委托“调用”来调用UI线程并调用Control.Invoke
/ BeginInvoke
。
例如,您可以使用:
textBox1.Invoke((MethodInvoker)(() => textBox1.Text = Convert.ToString(i)));
所有括号都会受到影响,所以如果你使用C#3.0,你可能想要添加这样的扩展方法:
public static void Invoke(this Control control, MethodInvoker action)
{
control.Invoke(action);
}
然后你可以这样做:
textBox1.Invoke(() => textBox1.Text = Convert.ToString(i));
答案 2 :(得分:0)
Windows窗体应用程序的主(“用户界面”)线程基本上是一个处理来自队列的消息的无限循环。当用户移动或单击鼠标,按下键等时,OS确定哪个应用程序应处理该输入并将消息添加到队列以用于适当的应用程序。当通知其消息队列包含消息时,应用程序将处理消息。例如,如果Windows窗体控件收到单击,则会触发由用户代码处理的Click事件。
这是您的代码所在的位置。在您的示例中,您为第一个命令按钮编写Click处理程序,该按钮运行通过更新UI的长循环。当您的代码正在运行时,不会处理来自队列的其他消息。这意味着没有处理其他控件(如命令按钮2)的点击。只有在Click处理程序返回后,消息循环才会继续处理事件。
要保持UI响应,可以将System.Windows.Forms.Timer设置为短间隔,并通过在循环中执行一次迭代来处理其Tick方法。这样,您只需为每个刻度线简单地绑定UI线程,并且可以在刻度线之间处理其他事件。
或者,您可以了解如何在后台线程上工作,但这可能不是最佳解决方案,因为您的点击处理程序中的大部分工作都是更新UI。从后台线程更新UI是不合法的;必须使用Control.Invoke
或Control.BeginInvoke
在UI线程上运行更新UI的方法,如Kai所讨论的那样。