在这里进行了一些搜索&在网上还没有找到一个好的答案。我要做的是在C#中的同一个类中调用两次按钮。
这是我的情景 -
我有一个带有“Go”按钮的表单。当我第一次点击它时,它会通过一些'for'循环(不停)来显示颜色范围。同时我将button1.Text属性设置为“Stop”。我希望能够第二次点击按钮,当发生这种情况时,我希望程序停止。基本上是一个走走停停的按钮。我知道如何使用2个按钮事件,但想使用1个按钮。
现在,结束程序的唯一方法是表单上的X按钮。
到目前为止,我尝试了不同的东西并且没有太多运气,所以想在这里询问大师如何去做。
顺便说一句,这是对 Head First Labs C#书籍练习的修改。谢谢!
〜阿伦
答案 0 :(得分:7)
您需要使用多线程(在单独的线程中异步启动进程密集型代码),例如,使用.NET 2+中的BackgroundWorker
对象。这是必要的,因为在完成Start方法中运行的循环之前,UI不会响应用户的单击。如果您使用相同的按钮或另一个按钮来切换过程,则无关紧要,因为处理器正忙于处理循环。
BackgroundWorker
有一个名为WorkerSupportsCancellation
的属性,在这种情况下需要为true。当用户单击“停止”时,您将调用CancelAsync
的{{1}}方法。
请参阅MSDN以获取一个好例子。另外DreamInCode有一个很好的教程,看起来非常类似于你的要求。
答案 1 :(得分:3)
为什么不创建两个按钮,当另一个可见时隐藏一个按钮?这应该更容易处理。
或者您可以添加一个bool字段来指示要执行的操作分支。
答案 2 :(得分:3)
一个简单的解决方案是在表单中添加一个布尔成员,例如,当按钮显示“Go”时为true
,当按钮显示为“Stop”时为false
。
然后,在按钮的事件处理程序中,检查该布尔值。如果值为true
,则在您将按钮的文本更改为“停止”时,启动操作并将值设置为false
。反之亦然。 :)
如果这是生产代码,我可能更喜欢其他技术,可能包括更仔细地考虑表单的设计,但由于这显然是一个学习练习,我相信一个简单的布尔标志,指示当前的状态表格正是您所需要的。
请注意,我强烈建议您不要检查按钮文本的值以确定对象所处的状态。只要有可能,作为良好设计的一般规则,您希望您的视觉状态与您的“解耦”基础对象的状态。也就是说,您的可视窗口小部件可以依赖于您的底层对象,但您的底层对象不应该依赖于您的可视窗口小部件。如果您测试了按钮的文本,那么您的基础逻辑将取决于您的视觉状态,这将违反此一般规则。
如果您的问题与您在执行操作时无法取消操作有关,那么您需要考虑使用BackgroundWorker来执行长时间运行的活动。
答案 3 :(得分:1)
另一种选择是检查按钮上的当前文本以确定要执行的操作:
void btnStartStop_Click(Object sender, EventArgs e)
{
if (btnStartStop.Text == "Go")
{
btnStartStop.Text = "Stop";
// Go code here
}
else
{
btnStartStop.Text = "Go";
// Stop code here
}
}
答案 4 :(得分:1)
您是否获得了第二次按键点击活动?在您的点击处理程序中放置一个断点并运行您的代码。当你第二次点击时,你有没有碰到你的断点?
如果您的循环连续运行,并且它位于您的按钮单击处理程序中,那么您的循环将在UI线程中运行。在循环完成之后,您可能无法“看到”第二个按钮单击。除了上面看到的分支代码之外,尝试在循环处理中插入一个DoEvents(这是一个你的循环暂时放弃控制以便可以处理消息的地方)。或者,(更好)查看backgroundworker类 - 在不同的线程中执行大部分处理,以便UI可以保持对按钮点击的响应。
答案 5 :(得分:1)
Cerebrus是关于使用Background Worker线程的。但是,如果您正在执行WPF应用程序,则它将无法直接更新UI。要解决此问题,您可以在主控制/窗口上调用Dispatcher.BeginInvoke。
给出如下代码:
Private Delegate Sub UpdateUIDelegate(<arguments>)
Private Sub CallUpdateUI(<arguments>)
control.Dispatcher.BeginInvoke(Windows.Threading.DispatcherPriority.Background, New UpdateUIDelegate(AddressOf UpdateUI), <arguments>)
End Sub
Private Sub UpdateUI(<arguments>)
'update the UI
End Sub
您可以从后台工作线程调用CallUpdateUI,它将获得执行UpdateUI的主线程。
答案 6 :(得分:0)
您可以将按钮上的Tag属性设置为布尔值,指示下一个操作应该是“停止”还是“开始”,并在每次单击按钮时重置它。但它是一个Object属性,所以当你阅读它时你必须将它强制转换为bool。