2016-03-10 2 views
-2

Это то, что я до сих порКнопка на форме не получает новый цвет

Private Sub BtnAnswerA_Clicked(sender As Object, e As EventArgs) Handles btnAnswerA.Click 
    Me.btnAnswerA.BackColor = Color.Green 
    System.Threading.Thread.Sleep(10000) 
    Me.Hide() 
    Q2.Show() 
End Sub 

Я хочу, когда кнопка нажата, она изменит цвет. Затем, через 10 секунд, он откроет другую форму. Но он ждет 10 секунд, прежде чем открывать следующую форму без изменения цвета.

+2

Используйте вместо этого таймер. 'Sleep' блокирует поток пользовательского интерфейса, так что ничего не происходит – Plutonix

+0

Позвольте мне дать вам совет - событие' Click' не происходит, когда выбрана кнопка. Это когда он щелкнут. Конечно, нет. Сначала вам нужно вызвать 'Application.DoEvents', поэтому ваша кнопка завершает перекраску –

+1

@ T.S. Использование 'Application.DoEvents' почти всегда является способом скрытия того, что вы делаете что-то неправильно в программе. –

ответ

-3

Смотрите в коде

Private Sub BtnAnswerA_Clicked(sender As Object, e As EventArgs) Handles btnAnswerA.Click 
    Me.btnAnswerA.BackColor = Color.Green 
    Application.DoEvents() ' <--- THERE 
    System.Threading.Thread.Sleep(10000) 
    Me.Hide() 
    Q2.Show() 
End Sub 

Что происходит, все, что происходит, происходит так быстро, ваша форма/кнопка не имеет времени, чтобы перекрасить. В этих случаях вы используете DoEvents, чтобы сообщить программе, чтобы завершить все сообщения в очереди, прежде чем обращаться с ними. Он заканчивает рисование, а затем начинает спать, отсюда появляется зеленая кнопка.

DoEvents приносит свои мнения. Мне нравится эта фотография https://stackoverflow.com/a/5183623/1704458

Люди настолько оскорблены DoEvents, но это меня никогда не подводило. ОК. Вот то, что я пишу для @Plutonix

private _timer As new System.Timers.Timer(10000) 
Private Sub Form_Load(sender As Object, e As EventArgs) 
    AddHandler _timer.Elapsed, AddressOf OnElapsed 
End Sub 

Private Sub BtnAnswerA_Clicked(sender As Object, e As EventArgs) Handles btnAnswerA.Click 
    Me.btnAnswerA.BackColor = Color.Green 
    Me.btnAnswerA.Enabled = False 
    _timer.Enabled = True 
End Sub 

Private Sub OnElapsed (sender As Object, e As ElapsedEventArgs) 
    _timer.Enabled = False 
    Me.btnAnswerA.Enabled = True 
    Me.Hide() 
    Q2.Show() 
End Sub 

Таймер Elapsed работает на другом потоке, так что ваша форма будет реагировать вместо замороженного

+0

oh wow, что просто спасибо огромное –

+0

@ T.S. Я не могу найти документацию о том, что Windows.Forms.Timer использует отдельный поток. В документации для [Windows.Forms.Timer Class] (https://msdn.microsoft.com/en-us/library/system.windows.forms.timer%28v=vs.110%29.aspx) указано следующее: «Это Таймер Windows предназначен для однопоточной среды, где потоки пользовательского интерфейса используются для выполнения обработки ». (Извините, я не хочу быть недобрым для вас, но вы пишете вещи, которые ошибочны.) –

+0

@AndrewMorton, вы в замешательстве. В моем примере используется 'System.Timers.Timer'. И вот MSDN: * Метод обработки событий может работать в одном потоке одновременно с тем, что другой поток вызывает метод Stop ... *, что означает, что команда 'Stop' может поступать из другого потока, кроме потока, на котором' Истекший пробег. Здесь: http://www.albahari.com/threading/part3.aspx - поиск ** Многопоточных таймеров ** –

1

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

Предполагая, что вы используете VS2010 или позже, ваш код может выглядеть примерно так:

Private Sub ShowNextForm(formToShow As Form, secondsDelay As Double) 
    Dim tim As New System.Windows.Forms.Timer 
    tim.Interval = CInt(secondsDelay * 1000) 
    tim.Start() 
    AddHandler tim.Tick, Sub(sender As Object, e As EventArgs) 
          tim.Stop() 
          tim.Dispose() 
          Me.Hide() 
          formToShow.Show() 
         End Sub 
End Sub 

Private Sub btnAnswerA_Click(sender As Object, e As EventArgs) Handles btnAnswerA.Click 
    Dim bn = DirectCast(sender, Button) 
    bn.Enabled = False 
    bn.BackColor = Color.Green 
    Dim nextForm As New Q2 
    ShowNextForm(nextForm, 10) 

End Sub 

Тогда, если вы имели другую кнопку, которую вы хотели сделать то же самое, скажем, «btnAnswer99» с формой Z99 и задержка 2,5 секунды, вам нужно будет только написать код

Private Sub btnAnswer99_Click(sender As Object, e As EventArgs) Handles btnAnswer99.Click 
    Dim bn = DirectCast(sender, Button) 
    bn.Enabled = False 
    bn.BackColor = Color.Blue 
    Dim nextForm As New z99 
    ShowNextForm(nextForm, 2.5) 

End Sub 

становится немного более продвинутые ... Может быть что-то, чтобы смотреть на потом ...

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

Итак, вы смотрите на то, что общего между всеми обработчиками щелчков кнопок, такими как все они имеют форму, в которой они находятся, форму для отображения, некоторые BackColor для изменения и задержку до отображения следующей формы, и, конечно, они относятся к a.

Это идеальная возможность для создания класса инкапсулировать все части, возможно, как-нибудь так:

Friend Class SetButtonToShowForm 

    Property thisForm As Form 
    Property nextForm As Form 
    Property buttonRef As Button 
    Property buttonBackColor As Color 
    Property secondsDelay As Double 

    Friend Sub ShowNextForm(currentForm As Form, formToShow As Form, secondsDelay As Double) 
     Dim tim As New System.Windows.Forms.Timer 
     tim.Interval = CInt(secondsDelay * 1000) 
     tim.Start() 
     AddHandler tim.Tick, Sub(sender As Object, e As EventArgs) 
           tim.Stop() 
           tim.Dispose() 
           currentForm.Hide() 
           formToShow.Show() 
          End Sub 

    End Sub 

    Friend Sub bnClick(sender As Object, e As EventArgs) 
     Dim bn = DirectCast(sender, Button) 
     bn.Enabled = False 
     bn.BackColor = Me.buttonBackColor 

     ShowNextForm(thisForm, nextForm, secondsDelay) 

    End Sub 

    Public Sub New() 
     ' empty constructor 
    End Sub 

    Public Sub New(sourceForm As Form, targetForm As Form, buttonRef As Button, backColor As Color, secondsDelay As Double) 
     Me.thisForm = sourceForm 
     Me.nextForm = targetForm 
     Me.buttonRef = buttonRef 
     Me.buttonBackColor = backColor 
     Me.secondsDelay = secondsDelay 
     AddHandler Me.buttonRef.Click, AddressOf bnClick 

    End Sub 

End Class 

, а затем вы можете настроить все кнопки в одной процедуре вдоль линий

Private Sub SetButtonHandlers() 
    Dim b1 As New SetButtonToShowForm(Me, Q2, btnAnswerA, Color.Green, 5) 
    Dim b2 As New SetButtonToShowForm(Me, z99, btnAnswer99, Color.Blue, 2.3) 
End Sub 

Таким образом, вы можете видеть, что с мало немного больше усилий, вы можете сделать это гораздо легче положить и p больше кнопок.

+0

Забавно даже, что вы тратите столько времени на это, когда у бедного парня он работает с 'DoEvents' –

Смежные вопросы