Почему моя форма такая застенчивая? - PullRequest
1 голос
/ 15 мая 2009

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

Хорошо, основываясь на совете из приведенных ниже ответов, я исключил подход с использованием потоков, и теперь моя программа выглядит следующим образом: Program.cs

 static void Main(){

Application.EnableVisualStyles();

Application.SetCompatibleTextRenderingDefault(false);

FrmWWCShell FrmWWCShell = null;
var splash = new FrmSplash();
splash.SplashFormInitialized += delegate
                                {
                                    FrmWWCShell = new FrmWWCShell();
                                    splash.Close();
                                };
Application.Run(splash);
Application.Run(FrmWWCShell);

}

И FrmSplash.cs вот так:

public partial class FrmSplash : Form
{

    public FrmSplash()
    {
        InitializeComponent();
    }

    protected override void  OnLoad(EventArgs e)
    {
        splashTimer.Interval = 1;
        splashTimer.Tick +=
            delegate { if (SplashFormInitialized != null) SplashFormInitialized(this, EventArgs.Empty); };
        splashTimer.Enabled = true;
    }

    public event EventHandler SplashFormInitialized;
}

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

Раскрась меня сильно растерялся сейчас!


ОРИГИНАЛЬНЫЙ ПОЧТА -> для справки

Я реализовал заставку «Загрузка приложения», которая работает в отдельном потоке, пока все dll загружаются, а форма становится «нарисованной». Это работает, как ожидалось. Странно то, что теперь, когда форма Splash закрывается, она отправляет мою основную форму обратно, если есть что-то еще открытое (, т.е. Outlook ). Я запускаю поток в Program.cs,

static class Program
{
    public static Thread splashThread;

    [STAThread]
    static void Main()
    {
        splashThread = new Thread(doSplash);
        splashThread.Start();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new FrmWWCShell());
    }

    private static void doSplash()
    {
        var splashForm = new FrmSplash();
        splashForm.ShowDialog();
    }
}

А потом я заканчиваю его, как только происходит мое событие FrmSearch_Shown.

private void FrmSearch_Shown(object sender, EventArgs e)
    {
        Program.splashThread.Abort();
        this.Show();
        this.BringToFront();
    }

Я, как вы можете видеть, пытался вызвать Show () и / или BringToFront () для FrmSearch, и он все еще " переходит " назад.

Чего мне не хватает?
Что еще можно попробовать?
Я делаю это настолько ужасно невежественным, что это мой процесс, который вызывает это?
Должен ли я подать заявление на досрочный выход на пенсию?

Спасибо за понимание!


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

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

Ответы [ 2 ]

5 голосов
/ 15 мая 2009

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

Вот техника, которую я использовал:

Используйте Application.Run в своей всплывающей форме, а не в «реальной» форме.

В вашей всплывающей форме есть инициализированное событие:

public event EventHandler SplashFormInitialized

Создайте таймер, который срабатывает за одну миллисекунду и запускает это событие.

Затем в своем методе запуска приложения вы можете загрузить свою реальную форму, затем закрыть свою всплывающую форму и выполнить Application.Run в реальной форме

var realForm = null;

var splash = new SplashForm();
splash.SplashFormInitialized += delegate {
  // As long as you use a system.windows.forms.Timer in the splash form, this
  // handler will be called on the UI thread
  realForm = new FrmWWCShell();
  //do any other init
  splash.Close();
}
Application.Run(splash); //will block until the splash form is closed

Application.Run(realForm);

Всплеск может включать в себя:

overrides OnLoad(...)
{
   /* Using a timer will let the splash screen load and display itself before
      calling this handler
   */
   timer.Interval = 1;
   timer.Tick += delegate {
     if (SplashFormInitialized != null) SplashFormInitialized(this, EventArgs.Empty);
   };
   timer.Enabled = true; 
}
0 голосов
/ 15 мая 2009

Попробуйте вызвать Application.DoEvents () сразу после шоу.

Предупреждение: не вызывайте DoEvents очень часто, но это один из тех случаев.

РЕДАКТИРОВАТЬ: Клайд заметил то, что я не сделал: вы это нить. Не запускайте пользовательский интерфейс в другом потоке. Вынуть ветку, оставить в приложении. DoEvents ().

...