C# 根据其他按钮激活或停用按钮
我是新来的。我有两个C# 根据其他按钮激活或停用按钮,c#,.net,winforms,button,C#,.net,Winforms,Button,我是新来的。我有两个按钮和两个标签。我想要的是,当我单击按钮1时,它开始计数并显示在标签1中。当我按下按钮2时,它会在按钮1下继续计数,并在按钮2下开始计数,并显示在标签2中。这是我的密码 bool testt = true; int i = 0; int j = 0; private void button1_Click(object sender, EventArgs e) { while (testt) { label1.Text = i.ToString
按钮
和两个标签
。我想要的是,当我单击按钮1
时,它开始计数并显示在标签1
中。当我按下按钮2
时,它会在按钮1
下继续计数,并在按钮2
下开始计数,并显示在标签2中。这是我的密码
bool testt = true;
int i = 0;
int j = 0;
private void button1_Click(object sender, EventArgs e)
{
while (testt)
{
label1.Text = i.ToString();
i++;
System.Threading.Thread.Sleep(50);
if (i > 5000)
{
i = 0;
}
}
}
private void button2_Click(object sender, EventArgs e)
{
testt = false;
while (!testt)
{
label2.Text = j.ToString();
j++;
System.Threading.Thread.Sleep(50);
if (j > 5000)
{
i = 0;
}
}
}
这里的问题是当我点击一个按钮时,它不允许我点击另一个按钮。我使用了一个全局变量来检测按下了哪个按钮。但它不起作用。我怎样才能做到这一点 这里的问题是线程问题 当您使用winforms时,主线程的任务是显示和使界面交互,并执行您赋予它的任何任务 在代码中,开始倒计时。但是在那里,使界面工作的同一个线程现在正忙于降低您的值,因此它在准备就绪之前不会更新界面或响应按钮 您需要的是一个助手线程来为您进行倒计时(或者老实说,启动一个计时器)。否则,在完成该循环之前,界面将是非交互式的 定时器是最简单的方法
您在UI线程上执行所有这些操作,因此您正在阻止它。您需要让另一个线程执行实际计数,并使用
控件将标签更改委托给主线程。调用,以便主线程有时间运行消息泵。您可以使用内置的BackgroundWorker
,或者使用ThreadPool
或TaskFactory
创建线程
我已经写了一个简短的例子,说明了如何使用LINQ和ThreadPool实现这一点,这不是设计方面的最佳方法,但它将为您提供一个开发适当解决方案的起点
semaphore = true;
int i = 0;
int j = 0;
private void button1_Click(object sender, EventArgs e)
{
semaphore = true;
ExecuteAsync(()=>
{
while (semaphore)
{
//Dispatch a call to the UI thread to change the label
Invoke((MethodInvoker)(() => ChangeLabel(label1, i.ToString())));
i++;
Thread.Sleep(50);
if (i > 5000)
{
i = 0;
}
}
});
}
//Executes a function on a ThreadPool thread
private void ExecuteAsync(Action action)
{
ThreadPool.QueueUserWorkItem(
obj => action());
}
private void ChangeLabel(Label label, string labelText)
{
label.Text = labelText;
}
private void button2_Click(object sender, EventArgs e)
{
semaphore = false;
ExecuteAsync(() =>
{
while (!semaphore)
{
//Dispatch a call to the UI thread to change the label
Invoke((MethodInvoker)(() => ChangeLabel(label2, j.ToString())));
j++;
Thread.Sleep(50);
if (j > 5000)
{
i = 0;
}
}
});
}
实际上这是另一个问题的总结。我只是在这里提出了这个概念。我需要知道如何在没有计时器的情况下完成这项工作。在这种情况下,您需要生成一个新线程,比如BackgroundWorker类。问题是,然后您需要委派单击任务,因为ui只能在主线程上完成。快速、简单且非常脏的修复方法是在循环中运行Application.DoEvents()。这可能会有所帮助:我尝试使用BackgroundWorker。在这种情况下,计数显示在标签中,但我仍然无法单击另一个按钮,当我单击按钮1时,它工作,当我单击按钮2时,它继续按钮1计数,并在按钮2下开始计数,但当我再次单击按钮1时,它不再工作,标签2继续计数。无论如何,谢谢你的解决方案非常感谢。你能给我一个ExecuteAsync方法教程的链接吗?ExecuteAsync方法是我们定义的,它利用了线程池。此链接应为您提供有关线程池使用的基本信息。祝你好运。再次感谢你的帮助。跟着这个走