2010-01-20 4 views
1

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

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

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

Другим потенциальным решением является использование multiple WPF UI threads, однако управление жизненным циклом и связь между окнами нетривиальны.

Вопросы:

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

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

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

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

Любые указатели на реализацию были бы высоко оценены!

+0

Какая версия Expresson Blend демонстрирует поведение, которое вы ищете? –

+0

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

+0

Последняя версия Blend (3) отличается. Сначала он показывает краткий всплеск Win32, затем всплеск WPF в течение длительного времени, затем он открывает главное окно, а затем открывает окно для выбора нового или существующего проекта. –

ответ

1

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

я бы:

  1. Создание классов для управления данными для окна "Select Project" (например, списки MRU, шаблоны и т.д.), убедившись, что они автономны и не требуют взаимодействия с основной нитью.

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

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

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

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

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

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

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

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, что свойство видимости главного окна обязан, но это можно сделать другими способами.

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

Да.

Если выбрать проект будет создан на основной поток & основной на другом потоке, или наоборот

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

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

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

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

Нет

0

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