2010-11-04 3 views
2

Ханс Пассант дал мне отличный ответ here, поэтому я подумал просить более подробную информацию, чтобы попытаться понять, как работает Application.Run().VB.Net: Понимание того, как работает Application.Run()

Насколько я понимаю из документов, кажется, что Application.Run() запускает цикл сообщений в текущем потоке, который по очереди позволяет обрабатывать ввод пользователя (это правильно?). Перегруженная версия Application.Run(Form) в основном делает то же самое, только она существует, когда форма закрывается, и она показывает форму по умолчанию.

Это поднимает несколько вопросов:

  • Как бы сделать, чтобы просто позвонить из Main() подразделов функции, которая может взаимодействовать с пользователем (окно сообщений и так далее) и ждать его выхода?
  • Когда цикл сообщений запускается без формы, как вы запускаете новую форму из этого цикла и дождитесь ее выхода? ShowDialog могла бы работать, если вы не хотите, чтобы форма немедленно отобразить при запуске
    • В принципе, ситуация будет выглядеть следующим образом (например, если у вас есть для этого запускаемую сворачивается в системный трей.): Суб `Main` имеет список задач для выполнения в 20mn, с иконкой в ​​системном трее, сообщающей пользователю, что программа будет работать в 20mn. Таймер гаснет после 20 минут, и он должен выполнить около ок. 15 задач один за другим, каждый раз создавая экземпляр диалогового окна прогресса, изначально скрытого в панели задач.
    • `ShowDialog` отобразит форму, которая не нужна; поэтому способ, которым я это сделал бы, - передать диалог прогресса обратному вызову функции, которая запускает следующую задачу. Но это не выйдет из первой формы прогресса до того, как вторая выйдет, не так ли? Что означает, что 15 форм в конечном итоге будут открыты ...
    • Таким образом, решение может заключаться в вызове (begininvoke?) Обратного вызова в основном цикле приложения ... Только, я не знаю, как это сделать, потому что я не имеет формы, связанную с петлей для вызова обратного вызова на ...

    Я надеюсь, что мои вопросы ясно (я мог бы смутить много вещей, извините),
    Спасибо,
    CFP.

    ответ

    3

    Отбросьте таймер, ProgressBar и BackgroundWorker на форме. Первое, что вам нужно сделать, - не допустить появления формы при запуске программы. Вставьте этот код в класс формы:

    Protected Overrides Sub SetVisibleCore(ByVal value As Boolean) 
        If Not Me.IsHandleCreated Then 
         value = False 
         Me.CreateHandle 
        End If 
        MyBase.SetVisibleCore(value) 
    End Sub 
    

    Используйте таймер, чтобы начать работу. Установите его Interval и Enabled свойства, добавьте обработчик события Tick:

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick 
        Me.Show() 
        ProgressBar1.Visible = True 
        Me.Enabled = False 
        BackgroundWorker1.RunWorkerAsync() 
    End Sub 
    

    Это делает форму видимой, когда работа начинается и начинается фон рабочего. Установите свойство WorkerReportsProgress в BGW к Истинному и добавить обработчик событий 3:

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
        '' Do stuff here, call BackgroundWorker1.ReportProgress to update the PB 
    End Sub 
    
    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged 
        ProgressBar1.Value = e.ProgressPercentage 
    End Sub 
    
    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted 
        ProgressBar1.Visible = False 
        Me.Enabled = True 
        Me.Hide() 
    End Sub 
    

    Это до вас, чтобы заполнить код для обработчика событий DoWork. Попросите ли вы выполнить эти 15 заданий, обязательно вызовите BackgroundWorker1.ReportProgess, чтобы обновить индикатор выполнения. Это то, что делает обработчик события ProgressChanged. Обработчик события RunWorkerCompleted снова скрывает форму.

    Вы можете вызвать метод Show() в событии элемента контекстного меню для NotifyIcon, чтобы пользователь мог снова сделать вашу форму видимой. Вызовите Application.Exit() в элементе контекстного меню, которое позволяет пользователю выйти из приложения. Убедитесь, что вы отключили это, когда BGW работает. Или реализуйте способ, чтобы чисто остановить работу.

    +0

    Ганс, вы определенно рок =) Спасибо за ваш подробный и полный ответ. Престижность вам :) –