WPF Startup Screen как Blend - PullRequest
       14

WPF Startup Screen как Blend

1 голос
/ 21 января 2010

Создание нашего главного окна WPF («Главное окно») занимает значительное время (оно использует ленту и панель стыковки, аналогично Visual Studio). Как и в Blend, первое действие всегда будет либо выбирать существующий проект для работы, либо создавать новый проект . Поэтому мы хотели бы показать это окно «Выбор проекта» как можно быстрее и создать тяжелое «Главное окно» в фоновом режиме (невидимым, пока пользователь не нажмет OK в окне «Выбор проекта»).

Как лучше всего спроектировать этот сценарий запуска, предпочтительно с использованием 2 окон WPF (одно для выбора проекта и одно для основного элемента управления)?

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

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

Вопросы:

Смогу ли я увидеть более быстрое время запуска при реализации 2-оконного решения WPF по сравнению с простым созданием «Основного окна» и без реализации окна «Выбор проекта» (при условии, что я могу найти реализация, которая заботится о временах жизни окна)?

Следует ли создать окно «Выбор проекта» в главном потоке приложения и «Главное окно» в фоновом потоке (или наоборот)?

Если мне нужно использовать окно запуска Win32 для скорости, как мне сообщить пользовательское имя проекта в главном окне приложения WPF ?

Кто-нибудь знает, как Blend на самом деле реализует свое окно запуска (которое я здесь пытаюсь имитировать)?

Будем весьма благодарны за любые указатели реализации!

Ответы [ 2 ]

1 голос
/ 23 января 2010

Лучший способ построить этот сценарий

Я бы:

  1. Создайте классы для управления данными для вашего окна «Выбор проекта» (например, списки MRU, шаблоны и т. Д.), Убедившись, что они автономны и не требуют взаимодействия с основным потоком.

  2. Хранить информацию о «текущем» проекте (ах) в объекте Application или в одноэлементном объекте.

  3. Создайте окно «Выбор проекта», чтобы работать полностью независимо от главного окна.

  4. Установите кнопки «Открыть» и «Создать» в окне «Выбор проекта» для запуска команды Application.Open и привяжите параметр CommandParameter к кнопке со свойством, которое содержит имя файла для открытия (или шаблон для экземпляр).

  5. Добавьте CommandBinding для команды Application.Open на уровне окна, чтобы принять параметр команды и установить текущий проект в объекте приложения.

  6. В коде запуска вашего приложения немедленно создайте поток, чтобы создать окно «Выбор проекта», затем сразу выполните {Dispatcher.Invoke с приоритетом ApplicationIdle, а затем несколько раз очень короткий Thread.Sleep}, затем продолжите , позволяя создать главное окно, но сделав его изначально невидимым.

  7. Установите триггер в главном окне, чтобы сделать его видимым, как только текущий проект был установлен в первый раз.

Вот как обработчик команды Open в окне «Выбрать проект» может обновить путь проекта в объекте приложения:

Application.Current.Dispatcher.Invoke(DispatcherPriority.Send, new Action(() =>
{
  ((App)Application.Current).CurrentProjectPath = e.Parameter;
}

Вот как будет выглядеть код запуска приложения:

public override void OnStartup(StartupEventArgs e)
{
  new Thread(() => { new SelectProject().Show(); }).Start();
  for(int i=0; i<10; i++)
  {
    Dispatcher.Invoke(DispatcherPriority.ApplicationIdle, () => {});
    Thread.Sleep(20);
  }
  _guts = new MainWindowContent(); // probably a UserControl
  _guts.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
  _guts.Arrange(new Rect(0, 0, guts.DesiredSize.Width, guts.DesiredSize.Height));
  _guts.SetBinding(VisibilityProperty,
    new Binding { Source = this, Path="StartupFinished",
                  Converter = BoolToVisibiltyConverter.Instance });

  _mainWindow = new MainWindow { Content = guts };
  // Note: Title and other properties of MainWindow would be set in the XAML
}

Запишите дополнительный код, чтобы убедиться, что кишки измерены и расположены заранее.

Вот код для установки текущего пути проекта:

public string CurrentProjectPath
{
  get { return _currentProjectPath; }
  set
  {
    _currentProjectPath = value;
    LoadProject();
    _startupFinished = true;
    OnPropertyChanged("StartupFinished");
  }
}

Этот код предполагает, что XAML связывает свойство видимости _mainWindow

StartupFinished - это DependencyProperty, с которым связано свойство Visibility главного окна, но это можно сделать другими способами.

Сможете ли вы увидеть более быстрое время запуска таким образом?

Да.

Должен ли выбранный проект создаваться в главном потоке, а основной - в другом, или наоборот

Вы должны создать MainWindow в главном потоке, чтобы он разделял тот же Dispatcher с объектом Application. Это означает, что «Выбор проекта» должен быть во втором потоке.

Если вам нужно использовать окно запуска Win32 для скорости

Возможно, это не обязательно. Запуск самого WPF занимает всего доли секунды. Но если это необходимо, описанная выше методика Application.Current.Dispatcher.Invoke будет работать.

Знаете ли вы, как Blend реализует свое окно запуска?

нет

Нет

0 голосов
/ 04 апреля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...