简体   繁体   English

使button.click事件做两件事

[英]Making a button.click event do two different things

I'm working on a simple VB.NET program (just using winforms) and am really terrible at UI management. 我正在开发一个简单的VB.NET程序(仅使用winforms),并且在UI管理方面确实很糟糕。 I'd like to have a single button that starts a process, and then have that same button stop the process. 我想要一个按钮来启动一个过程,然后用相同的按钮来停止该过程。

I'm thinking about having the main form initiate a counter, and the Click event iterate the counter. 我正在考虑让主窗体启动一个计数器,并在Click事件中迭代该计数器。 Then it does a simple check, and if the counter is even it will do thing A and odd does thing B. 然后它执行简单的检查,如果计数器是偶数,它将执行A事情,而奇数则执行B事情。

Is there a better way, aside from using two buttons or stop/start radio buttons? 除了使用两个按钮或停止/启动单选按钮以外,还有没有更好的方法?

I've done that exact thing one of two ways. 我已经通过两种方法之一完成了该操作。 You can use a static variable or toggle the text of the button. 您可以使用静态变量或切换按钮的文本。

Since your button has two functions, Good design requires you to indicate that to the user. 由于按钮具有两个功能,因此“好的设计”要求您向用户指示。 The following code assumes the Button's text is set in Design Mode to "Start", and the code to start and stop your process is in the Subs StartProcess and EndProcess. 下面的代码假定Button的文本在“设计模式”下​​设置为“开始”,而开始和停止过程的代码在Subs StartProcess和EndProcess中。

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 编辑

The above solution is fine for a single-language application developed by a small number of developers. 对于由少量开发人员开发的单语言应用程序,上述解决方案是合适的。

To support multiple languages, developers typically assign all text literals from supporting files or databases. 为了支持多种语言,开发人员通常会分配支持文件或数据库中的所有文本文字。 In larger development shops, with multiple programmers, using a display feature of the control for flow-control may cause confusion and regression errors. 在具有多个程序员的大型开发商店中,使用控件的显示功能进行流控制可能会导致混淆和回归错误。 In those cass, the above technique wouldn't work. 在这种情况下,上述技术将无法正常工作。

Instead, you could use the Tag property of the button, which holds an object. 而是可以使用包含对象的按钮的Tag属性。 I would typically use a Boolean, but I used a string just to make more clear as to what's going on. 我通常会使用布尔值,但是我使用了一个字符串只是为了更清楚地了解发生了什么。

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

This is example in pseudo-code. 这是伪代码中的示例。 I don't guarantee that names of methods and event are exactly match real names. 我不保证方法和事件的名称与真实名称完全匹配。 But this should provide you a design that you could use for responsive form. 但这应为您提供可用于响应形式的设计。

Lets say, your process is running on separate tread, using BackgroundWorker . 可以说,您的进程正在使用BackgroundWorker在单独的踏板上运行。 You setup your worker and start process 您设置工作人员并开始流程

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 You have to substitute identifiers with real names and create you state or data object, which will carry information from background thread to UI thread, and also an Enum Status that can be part of your custom state object. 在这里,您可以查明方法和事件的名称。您必须用真实名称替换标识符,并创建状态数据对象,该状态数据对象将从后台线程到UI线程的信息以及可能属于自定义状态的Enum Status一起携带宾语。 This should work once translated into real code 一旦翻译成真实代码,这应该可以工作

Just want to show another approach for this task Use .Tag property for your own purpose If .Tag Is Nothing (by default in designer) then start process 只是想展示此任务的另一种方法将.Tag属性用于您自己的目的如果.Tag不存在(默认情况下,在设计器中),则开始处理
If not Nothing -> stop process 如果不是,则->停止进程

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM