MessageBox.Show отправляет главную форму на задний план
От: sVenom Россия  
Дата: 28.07.10 13:13
Оценка:
Коллеги,
Столкнулся со следующей проблемой. Имеется оконное приложение. Иногда оно выполняет длительные операции. В таких случаях в отдельном потоке запускается другое окно методом Application.Run(), в котором имеется ProgressBar. Как только длительный процесс завершается, главное окно сообщает об этом дочернему и оно закрывается. Все работало нормально до тех пор, пока не потрбовалось показывать диалоговое окно после завершения длительной операции. Теперь после того, как я жму на кнопку Ок диалогового окна, главное окно приложения по какой-то причине оказывается...позади всех активных окон Windows.
Привожу код:
1. Класс формы с ProgressBar
public partial class ProgressForm : Form
{
    private int numberOfOperations;

    public ProgressForm(int numberOfOpertaions, string initialMessage)
    {
        // стандартная инициализация + задаю размер шага progressBar 
        ...
        this.ShowInTaskbar = false;
        this.ControlBox = false;
    }

    // Этот метод вызывается из другого потока, что бы сообщить о следующем шаге
    public void ReportProgress(string message)
    {
        if (this.InvokeRequired)
        {
            BeginInvoke(new MethodInvoker(delegate() { ReportProgress(message); }));
        }
        else
        {
            pb.PerformStep();
            lblStatus.Text = message;
            this.Refresh();
        }
    }

    // Когда длительная операция завершена, другой поток инициирует закрытие этого окна
    public void CloseForm()
    {
        if (this.InvokeRequired)
        {
            BeginInvoke(new MethodInvoker(delegate() { this.Dispose(false); }));
        }
        else
        {
            this.Dispose(false);
        }
    }
}


2. Класс Program

static class Program
{
    ...
    private static ProgressForm pf;
    ...
    // Открываем форму
    public static void ShowProgressForm(int numberOfOperations, string initialMessage)
    {
        ThreadStart starter = delegate 
        {
            pf = new ProgressForm(numberOfOperations, initialMessage);
            Application.Run(pf);
        };
        new Thread(starter).Start();
    }

    // Прогресс
    public static void ReportProgress(string message)
    {
        pf.ReportProgress(message);
    }

    // Закрываем
    public static void CloseProgressForm()
    {
        pf.CloseForm();
    }
    ...

    [STAThread]
    static void Main()
    {
        ...
        Application.Run(new MainForm());
    }
    
}


3. Наконец главная форма

public partial class MainForm
{
    ...

    public void HeavyFunction(...)
    {
        Program.ShowProgressForm(...);
        // Выполняем различные операции, иногда сообщаем о прогрессе
        ...
        Program.ReportProgres(...);
        ...
        // Закрываем
        Program.CloseProgressForm();
        
        // А вот теперь вызываем диалоговое окно, что бы сообщить пользователю об окончании операции
        
        MessageBox.Show(..., MessageBoxButtons.Ok, ...);
    }
}


Собственно проблема возникает, когда я взываю MessageBox.Show() и жму на Ok — главная форма оказывается позади всех активных окон. Если просто выполнять функцию без вызова ProgressForm в другом потоке — все Ок. Если вызывать ProgressForm, но не вызывать MessageBox.Show() — тоже все в порядке. Подскажите пожалуйста в чем может быть проблема. На мой взгляд либо все решается одной строкой, либо я что-т опринципиально сделал не правильно и придется пересмотреть архитектуру.

Спасибо.


28.07.10 23:56: Перенесено модератором из '.NET' — TK
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.