Установить переменную или ссылку на уже открытую форму - PullRequest
0 голосов
/ 09 января 2012

Я новичок в c # и не могу разобраться с объявлением переменных.

У меня есть длинный процесс, который я отправил фоновому работнику. Пока longyprocess делает свое дело, отображается форма, говорящая пользователю ждать. Когда longyprocess завершится, я хочу закрыть форму ожидания.

Как мне сослаться на уже существующий экземпляр формы ожидания, чтобы я мог закрыть ее в процессе закрытия фонового рабочего? Процесс закрытия находится в частном пустоте, отличном от того, в котором была открыта форма ожидания, и я не могу объявить форму за пределами частного вакуума.

Любая помощь будет принята с благодарностью.

Спасибо ...

Ответы [ 7 ]

1 голос
/ 09 января 2012

Если вы имеете в виду класс BackgroundWorker в .NET, у него есть событие RunWorkerCompleted .Просто зарегистрируйте обработчик событий, чтобы закрыть форму.

EDIT

Лучше всего прочитать документацию MSDN для BackgroundWorker .Обратите внимание, что есть 2 примера, второй лучше, так как первый не содержит регистрационный код события, который полезен для понимания.И в нижней части страницы приведен пример, предоставленный комментатором, который довольно хорош ( BGW нюансы, включая пример с ProgressBar ).

Может быть, эта схема полезна:

  1. Ваша MainForm создает экземпляр WaitForm (a ProgressBar ?)
  2. Ваша MainForm создает экземпляр BackgroundWorker
  3. Ваша MainForm имеет соответствующие обработчики событий для событий BackgroundWorker и ProgressBar.
  4. Панель ProgressBar не обязательно должна быть явно закрыта.
0 голосов
/ 10 января 2012

Для тех, кого это может касаться:

Используя очень полезный код BalamBalam, мне удалось заставить его работать следующим образом:

           class DatabaseUpdater
{ 
// Declare the background worker and WaitForm at Class Level
static BackgroundWorker bw;
public static Form WaitForm;


public static void DelegateWorkStuff()
{

    // Set up the background process and show WaitForm in here        

    bw = new BackgroundWorker();
    bw.WorkerReportsProgress = true;

    WaitForm = new WaitForm();
    WaitForm.Show();

    bw.DoWork += bw_DoWork;
    bw.ProgressChanged += bw_ProgressChanged;
    bw.RunWorkerCompleted += bw_RunWorkerCompleted;
    bw.RunWorkerAsync();
 }

   static void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        //Run the lenghty code/processes in here
    }

   static void bw_RunWorkerCompleted (object sender, RunWorkerCompletedEventArgs e)
   {
        //Close the Waitform thus
        WaitForm.Close();
   }
0 голосов
/ 10 января 2012

Вы не опубликовали свой код для формы ожидания, так что я вроде должен догадаться.Короче говоря, вам нужна закрытая переменная на уровне класса для закрытия.Это проверенный код.

public partial class MainWindow : Window
{
    NavigationWindow winWait;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void btnShow(object sender, RoutedEventArgs e)
    {
        if (winWait != null) return; 
        winWait = new NavigationWindow();
        winWait.Content = new PageWait();
        winWait.Show();
    }

    private void btnHide(object sender, RoutedEventArgs e)
    {
        if (winWait != null) winWait.Close();
    }

}

Если вы хотите иметь несколько форм «ожидания», вам нужно немного повеселиться.Вы не будете иметь переменную Navigation в классе, а создадите ее и передадите в фон, чтобы она могла быть передана обратно в обратный вызов.И вам нужно иметь дело с! = Ноль, но не активным.

0 голосов
/ 09 января 2012

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

public class FormWait
{
     private static FormWait frm = new FormWait();

     public static void ShowForm(string message)
     {
         Show(message);
     }

     public static void Close()
     {
         Application.Current.Dispatcher.Invoke(new Action(() =>
            {
                  if(!frm.Visible)
                      return;

                  frm .Close();
            }));


     }

     private void Show(string str)
     {
       Application.Current.Dispatcher.Invoke(new Action(() =>
            {
                 if(frm.Visible)
                    frm.Close();
                 lblMessage.Text = message; // assume that there is a label on the Form to show the message

                  frm .Show();
            }));


     }

   } 

Просто идея.

0 голосов
/ 09 января 2012

Посмотрите на BackgroundWorker и , как его использовать .Есть вся информация, которая вас интересует.

0 голосов
/ 09 января 2012

Объявите форму в классе, но вне метода:

Form2 frm2 = new Form2();

Но покажите его, когда необходимо: (-в методе)

frm2.Show();

(Мой ответ дляwinforms. Теперь я заметил, что вы имеете в виду wpf. Я не знаю, работает ли он так же.)

0 голосов
/ 09 января 2012

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

C # Как фоновый поток сообщает потоку пользовательского интерфейса, что он что-то завершил?

...