Подпишись на наш Twitter

Быть в курсе появления новых статей!

И снова здравствуйте и добро пожаловать в следующую статью нашей серии уроков про Caliburn Micro. Это относительно простой урок на этот раз, мы будем рассматривать Window Manager. Прежде чем мы начнем, вот ссылки на предыдущие уроки в этой серии:

Многие из вас, кто играл с Caliburn Micro могут знать, что существует не так много упоминали о Window Manager. В связи с этим, я не буду рассказывать все о Window Manager, я просто объясню, что я знаю об этом. Чтобы продемонстрировать, как использовать Window Manager, мы будем расширять приложение, которое мы сделали в первом посте блога этой серии.

Использование Window Manager

Возможно, вы помните по первой статье, что одна из первых вещей, которые мы сделали, было удаление MainWindow.xaml из проекта. Caliburn Micro позаботится об инициализации окна, установив его контекст данных и отображение для соответствующего представления для нас. Window Manager является одним из механизмов, ответственных за этого. Когда вы запускаете приложение, построенное с Caliburn Micro, Window Manager автоматически используется для создания загрузочного окна. Для небольших приложений, это все, что вам действительно нужно знать об Window Manager. Когда вы строите большие приложения, которые отображают другие окна или диалоги, то сейчас самое время, чтобы узнать, как использовать оконный менеджер. Для демонстрации мы добавим кнопку в приложение, которая откроет новое окно при нажатии. Начните с добавления кнопки AppView.xaml и метода перехвата события щелчка в AppViewModel.cs. Вы можете сделать это, используя соглашения Caliburn Micro, как описано в предыдущих уроках. Я назвал этот метод "OpenWindow". В методе OpenWindow нам необходимо иметь доступ к экземпляру Window Manager. Хотя мы могли просто создать новый экземпляр WindowManager и использовать, но лучше получить глобальный экземпляр Window Manager, который Caliburn Micro делает доступными для приложения. Мы можем сделать это, создав конструктор AppViewModel.cs, который принимает IWindowManager и хранить его в поле. Возможно, вы помните из 4-й части этой серии о том, что необходимо сделать при создании конструктора для модели представления, которая имеет по крайней мере один параметр. Вот 3-и простых шага:

1. Обновите bootstrapper. Не забудьте добавить System.ComponentModel.Composition.dll в качестве ссылки для вашего проекта.

using Caliburn.Micro;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
 
public class AppBootstrapper : Bootstrapper<AppViewModel>
{
  private CompositionContainer container;
 
  protected override void Configure()
  {
    container = new CompositionContainer(new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()));
 
    CompositionBatch batch = new CompositionBatch();
 
    batch.AddExportedValue<IWindowManager>(new WindowManager());
    batch.AddExportedValue<IEventAggregator>(new EventAggregator());
    batch.AddExportedValue(container);
 
    container.Compose(batch);
  }
 
  protected override object GetInstance(Type serviceType, string key)
  {
    string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
    var exports = container.GetExportedValues<object>(contract);
 
    if (exports.Count() > 0)
    {
      return exports.First();
    }
 
    throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
  }
}

2. Использование атрибута Export для класса AppViewModel:

[Export(typeof(AppViewModel))]
public class AppViewModel : PropertyChangedBase
{
  ...
}

3. Использование атрибута ImportingConstructor для конструктора AppViewModel:

private readonly IWindowManager _windowManager;
 
[ImportingConstructor]
public AppViewModel(IWindowManager windowManager)
{
  _windowManager = windowManager;
}

Теперь мы можем использовать экземпляр Window Manager в нашем методе OpenWindow, чтобы открыть новое окно. Чтобы упростить этот пример, мы просто создаем новое окно, которое также использует AppViewModel в зависимости от контекста данных. Это делается с помощью следующего кода:

public void OpenWindow()
{
  _windowManager.ShowWindow(new AppViewModel(_windowManager));
}

Запустите и нажмите кнопку, чтобы увидеть как другое окно появляется. Все, что нам необходимо сделать, это передать экземпляр модели представления, а все остальное от создания экземпляра окна и отображения соответствующего представления для нашей модели представления будет сделно за нас. Еще раз Caliburn Micro делает нашу жизнь проще!

Window Manager имеет все виды методов и их перегрузок для открытия окон, диалоговых окон и всплывающих окон. Все эти методы довольно просты в использовании. Вы можете видеть больше использование Window Manager в примере HelloWindowManager, который поставляется с Caliburn Micro. Еще одна вещь, на которую я хотел обратить внимание этот параметр "настройки". Здесь вы можете передать параметры в динамический объект для установки свойств нового окна. Это дает вам полный контроль над внешним видом вашего приложения, если вам это нужно. Вот пример, где я устанавливаю WindowStartupLocation вручную, а не по центру создателя.

public void OpenWindow()
{
  dynamic settings = new ExpandoObject();
  settings.WindowStartupLocation = WindowStartupLocation.Manual;
 
  _windowManager.ShowWindow(new AppViewModel(_windowManager), null, settings);
}

Кастомизирование Window Managers

Есть сценарии, где полезно реализовать собственный диспетчер окон. Это нужно, если вам нужно установить свойства всех экземпляров окон общими значениями. Например, свойства могут включать в себя иконки, состояние окна, размер окна и применения пользовательских оформления. Самое полезное свойство, которое я нашел, чтобы установить для окон это свойство SizeToContent. По умолчанию Caliburn Micro устанавливает его в значение SizeToContent.WidthAndHeight. Это означает, что окно автоматически меняет размер в зависимости от содержания. Хотя это может быть удобно время от времени, я обнаружил, что это вызывает некоторые проблемы с некоторыми областями разметки приложения и кажется глючным при установке окна в максимальный размер по умолчанию. Создание кастомного Window Manager очень просто. Начните с добавления класса, который расширяет WindowManager. Далее, вы можете переопределить метод EnsureWindow и сделать что-то вроде следующего:

protected override Window EnsureWindow(object model, object view, bool isDialog)
{
  Window window = base.EnsureWindow(model, view, isDialog);
 
  window.SizeToContent = SizeToContent.Manual;
 
  return window;
}

В этом методе мы начинаем с вызова base.EnsureWindow() для создания экземпляра окна. Далее вы можете задавать любые свойства окна, которые вы хотите, а затем просто вернуть экземпляр окна. Последним шагом является создание экземпляра вашего менеджера окон для глобального использования в приложении. В первом фрагменте кода в этой статье мы внесли изменения в загрузчик. Здесь вы можете видеть, что мы добавляем экземпляра WindowManager в CompositionBatch. Вы можете заменить это, для использования экземпляра вашего менеджера окон вместо этого, что будет выглядеть следующим образом:

batch.AddExportedValue<IWindowManager>(new AppWindowManager());

Вот и все, что я хотел рассказать о Вот все, что я хотел, чтобы покрыть с оконным менеджером, я надеюсь, что вы сочли полезным в создании больших приложений WPF использование Caliburn Micro! Я ценю ваши комментарии и отзывы о серии!

Скачать полную версию проекта Visual Studio 2010.

Удачи в кодировании :)

Оригинал: Caliburn Micro Part 5: The Window Manager




Дата публикации: 13.03.2012 13:00

Ярлыки: Caliburn.Micro, WPF