2014-12-06 3 views
0

Я работаю над простой программой VB.NET (просто используя winforms) и ужасно себя чувствую при управлении пользовательским интерфейсом. Я хотел бы иметь одну кнопку, которая запускает процесс, а затем эту ту же кнопку останавливает процесс.Создание события button.click делает две разные вещи

Я думаю о том, что основная форма инициирует счетчик, а событие Click перебирает счетчик. Затем он делает простую проверку, и если счетчик даже будет делать вещь A и нечетная вещь B.

Есть ли лучший способ, помимо использования двух кнопок или кнопок остановки/запуска?

+1

Вы можете использовать текст кнопки, чтобы переключать то, что он делает.Когда они нажимают кнопку, проверьте текст - если это = «Пуск», затем измените его на «Стоп», иначе измените его и пока вы находитесь в этом коде if/else, для которого вы находитесь. – OneFineDay

+0

Duh. Я забыл, что каждый атрибут объекта также можно проверить. Это дает больше смысла, чем запуск счетчика, который я больше не могу использовать. –

+0

Вы также можете использовать RadioButton с параметром «Внешний вид», который будет действовать как переключатель, который больше похож на то, что делает пользовательский интерфейс. – Plutonix

ответ

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 

РЕДАКТИРОВАТЬ

Вышеуказанный раствор прекрасно подходит для применения в одноязычном разработанном небольшом числе разработчиков.

Для поддержки нескольких языков разработчики обычно присваивают всем текстовым литералам поддержку файлов или баз данных. В крупных магазинах разработки с несколькими программистами использование функции отображения элемента управления для управления потоком может вызывать ошибки путаницы и регрессии. В этих случаях эта техника не работает.

Вместо этого вы можете использовать свойство тега кнопки, которая содержит объект. Я бы обычно использовал логическое значение, но я использовал строку, чтобы лучше понять, что происходит.

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

+0

Согласился, что это не идеальное решение в каждом случае. –

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 Вы должны заменить идентификаторы с реальными именами и создать вам состояние или данные объект, который будет нести информацию из фонового потока в поток пользовательского интерфейса, а также Enum Status, который может быть частью вашего пользовательского объекта состояния. Это должно работать, как только переводится в реальный код

+0

Хорошее использование фонового процесса. Если пользователь будет делать что-то еще с программным обеспечением, это хорошая функция. Но разве это не добавляет бремени написания потокобезопасного кода, так что один поток (текущий поток переднего края) не наступает или не прерывает фоновый поток? –

+0

@AndrewNeely Документация Microsoft на это отвечает: 'Вы должны быть осторожны, чтобы не манипулировать объектами пользовательского интерфейса в обработчике событий DoWork. Вместо этого общайтесь с пользовательским интерфейсом через события ProgressChanged и RunWorkerCompleted. Другими словами, если вы используете предоставленные события, вам не нужно писать какой-либо специальный код. –

1

Просто хочу показать другой подход к этой задаче Используйте .Tag свойство для собственных целей Если .Tag ничего не сообщил (по умолчанию в конструкторе), а затем начать процесс
Если нет ничего -> stop

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 
Смежные вопросы