2014-12-06 53 views
0

我工作的一个简单的VB.NET程序(只是用的WinForms)和我在UI管理真的很可怕。我想要一个按钮来启动一个进程,然后让这个按钮停止进程。制作button.click事件做两个不同的东西

我在想具有主要形式启动计数器,Click事件迭代计数器。然后执行一个简单的检查,如果计数器即使它会做的事情A和使用两个按钮奇做的事情B.

有没有更好的办法,撤销或停止/启动单选按钮?

+1

您可以使用按钮的文本来切换它的功能。当他们点击按钮检查文本 - 如果它=“开始”,然后将其更改为“停止”,否则将其更改回来,而当你在这个if/else代码中,你在哪个阶段。 – OneFineDay 2014-12-06 02:10:04

+0

Duh。我忘记了对象的每个属性都是可测试的。这比启动一个我可能不会再使用的计数器更有意义。 – 2014-12-06 02:14:00

+0

你也可以使用一个RadioButton,其外观设置为Button,它可以更像UI所做的切换 – Plutonix 2014-12-06 13:55:05

回答

3

我已经完成了确切的事情两种方式之一。您可以使用静态变量或切换按钮的文本。

因为你的按钮有两个功能,良好的设计需要您来指示给用户。以下代码假定按钮的文本在设计模式中设置为“开始”,启动和停止您的进程的代码位于子进程进程和进程结束进程中。

Public Sub Button1_Click(ByVal Sender as Object, ByVal e as System.EventArgs) 
    If Button1.Text ="Start" Then 
      StartProcess() 
      Button1.Text="End" 
    Else 
      EndProcess() 
      Button1.Text="Start" 
    End IF 
End Sub 

EDIT

上述溶液是细用于通过少量的开发者开发的单语言应用。

支持多国语言,开发人员通常从支持文件或数据库分配所有的文本文字。在较大的开发商店中,对于多个程序员,使用流控制控件的显示功能可能会导致混淆和回归错误。在这些cass中,上述技术不起作用。

相反,您可以使用该按钮,其中包含对象的Tag属性。我通常会使用布尔值,但是我使用了一个字符串,以便更清楚地了解发生了什么。

Public Sub New() 
    'Initialize the Tag 
    Button1.Tag="Start" 
End Sub 
    Public Sub Button1_Click(ByVal Sender as Object, ByVal e as System.EventArgs) 
     If Button1.Tag.ToString="Start" Then 
       StartProcess() 
       Button1.Tag="End" 
     Else 
       EndProcess() 
       Button1.Tag="Start" 
     End IF 
    End Sub 
+0

这是一个很好的工作解决方案,但是在开发中可能会出现一些场景,工作。例如,本地化 - 如果语言改变,'Button1.Text'将不起作用。或者我可以想象,当另一个开发人员希望在设计器中将“Button1.Text”更改为“完成”而不检查代码时。 – Fabio 2014-12-08 14:43:38

+0

一致认为它不是每个实例中的完美解决方案。 – 2014-12-08 16:10:09

3

这是伪代码中的示例。我不保证方法和事件的名称完全匹配真实姓名。但是这应该为您提供一种可以用于响应式表单的设计。

可以说,您的流程是在单独的步骤上运行的,使用BackgroundWorker。 你设置你的工人,并开始处理

Class MyForm 

    private _isRunning as boolean 
    private _bgWorker as BackgroundWorker 

    sub buton_click() 
     If Not _isRunning Then 
      _isRunning = true; 
      StartProcess() 
     Else 
      StopProcess() 
     End if 
    end sub 

    sub StartProcess() 
     ' Setup your worker 
     ' Wire DoWork 
     ' Wire on Progress 
     ' wire on End 
     _bgWorker.RunWorkerAsync() 
    End sub   

    sub StopProcess() 
     if _isRunning andAlso _bgWorker.IsBusy then 
      ' Send signal to worker to end processed 
      _bgWorker.CancelAsync() 
     end if 
    end sub 

    sub DoWork() 
     worker.ReportProgress(data) ' report progress with status like <Started> 
     ' periodically check if process canceled 
     if worker.canceled then 
      worker.ReportProgress(data) ' report progress with status like <Cancelling> 
      return 
     end if 

     ' Do your process and report more progress here with status like <In Progress> 
     ' and again periodically check if process canceled 
     if worker.canceled then 
      worker.ReportProgress(data) ' report progress with status like <Cancelling> 
      return 
     end if 

     worker.ReportProgress(data) ' report progress with status like <Ending> 

    end sub 

    sub ReportProgress(data) 
     if data = <some process state, like "Started"> then 
      btnProcess.Text = "End Process" 
     end if 


    End sub 

    sub ReportEndOfProcess 
     btnProcess.Text = "Start Process" 
     _isRunning = false 
    end sub 

End Class 

Here you can pinpoint the names of methods and events 你需要替换用实际名称标识符,并创建状态数据对象,将携带的信息从后台线程UI线程,也一个Enum Status可以是您的自定义状态对象的一部分。这应该工作,一旦翻译成真正的代码

+0

很好的使用后台进程。如果用户将要使用该软件做其他事情,这是一个很好的功能。但是,这不会增加编写线程安全代码的负担,例如一个线程(当前的前台线程)不会踩到或破坏后台线程? – 2014-12-06 22:11:01

+0

@AndrewNeely Microsoft文档回答说:'您必须小心,不要操作DoWork事件处理程序中的任何用户界面对象。相反,通过ProgressChanged和RunWorkerCompleted事件与用户界面进行通信。换句话说,如果使用提供的事件,则不需要编写任何特殊代码。 – 2014-12-06 23:17:57

1

只是想表明另一种方法完成这个任务 使用.Tag财产为自己的目的 如果.Tag是Nothing(默认情况下,设计师),然后开始处理
如果不是没有 - >停止过程

Public Sub Button1_Click(ByVal Sender as Object, ByVal e as System.EventArgs) 
    If Me.Button1.Tag Is Nothing Then 
     StartProcess() 
     Me.Button1.Tag = New Object() 
     Me.Button1.Text = "End" 
    Else 
     EndProcess() 
     Me.Button1.Tag = Nothing 
     Me.Button1.Text = "Start" 
    End 
End Sub