Reputation: 2301
I'm working on a simple VB.NET program (just using winforms) and am really terrible at UI management. 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. Then it does a simple check, and if the counter is even it will do thing A and odd does thing B.
Is there a better way, aside from using two buttons or stop/start radio buttons?
Upvotes: 0
Views: 3227
Reputation: 908
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.
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. 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
Upvotes: 3
Reputation: 32445
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
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
Upvotes: 1
Reputation: 19340
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
.
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. This should work once translated into real code
Upvotes: 3