Prism 4 RegionManager теряет первый регион, когда второй добавляется в WPF - PullRequest
1 голос
/ 16 мая 2011

Мы используем Castle Windsor и Prism 4 (февраль 2010 г.). Мы используем загрузчик Windsor, который делает Castle приятным с Prism, выпущенным в пакете CompositeWPFContrib.

Я пытаюсь определить регионы в XAML моей основной оболочки. Если я определю один регион, например, так:

<ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.ToolBarRegion}"
                    DockPanel.Dock="Top"/>

А затем выполните одно из следующих действий в одном из моих методов инициализации модулей:

_regionManager.Regions[RegionNames.ToolBarRegion].Add(typeof(SomeView));

... жизнь прекрасна.

Однако, как только я добавлю еще один регион в XAML оболочки:

<ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.WorkspaceRegion}"
                    DockPanel.Dock="Bottom"/>

А затем сделайте:

_regionManager.Regions[RegionNames.WorkspaceRegion].Add(typeof(SomeOtherView));

... Я получаю сообщение об ошибке: «Администратор региона не содержит регион ToolBarRegion.»

Что дает? Как только я закомментирую второй регион, он находит первый, а когда я добавляю второй регион обратно, он взрывается, как будто RegionManager отказывается хранить коллекцию регионов. Надо сказать, что это мой первый набег в Касл Виндзор и Призму, так что не исключено, что я здесь упускаю что-то болезненно очевидное. Любой свет, который мог бы пролиться на это, был бы самым полезным.

1 Ответ

0 голосов
/ 17 мая 2011

Вы уверены, что к DockPanel вы добавляете свои элементы управления?Может быть, ваш контейнер сам по себе является элементом управления контентом (вид элемента управления, который принимает только одного дочернего элемента)?

Кроме того, вы можете попробовать зарегистрировать менеджера региона в загрузчике:

RegionManager.SetRegionManager(shell, this.Container.Resolve<IRegionManager>());

См. Следующеевопросы:

Не удается найти регион в RegionManager (с помощью PRISM)

WPF, Prism v2, регион в модальном диалоговом окне, добавить регион в коде позади

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

Я посмотрел пример решения (ссылка в комментариях) и обнаружил, что ваш код внедрения представления выполняется перед созданием основного представления.Инициализаторы вашего модуля вызываются в StartRuntime-> CreatePrismBootStrapper, а DisplayRootView (который создает вашу оболочку) вызывается позже.Конечно, он не может найти регион, когда оболочка еще не была создана.

Если все, что вы хотите зарегистрировать в своих субконтролях в коде инициализации модуля, более подходящим является обнаружение представления - оно не 'т ваша оболочка должна быть уже создана .Инъекция представлений лучше, когда вам нужно переключать представления на основе пользовательского ввода (в этом случае вам нужно убедиться, что содержащий элемент управления зарегистрирован).

У вас есть несколько вариантов:

  1. Использовать обнаружение представлений - как вы делали в примере решения.

  2. Создайте и зарегистрируйте свой экземпляр Shell перед загрузкой модулей.base.DisplayRootView () должен быть в состоянии найти его в контейнере, чтобы он не создавал другой.Один из способов, но я не уверен, что лучше:

PrismBootstrapper.cs:

protected override DependencyObject CreateShell()
{
    Thor.Application.Views.ShellView view = new Thor.Application.Views.ShellView();
    _container.Register(Castle.MicroKernel.Registration.Component.For<Thor.Application.Views.ShellView>().Instance(view));
    // _container.Resolve<Thor.Application.Views.ShellView>();

    return view;
}

.3.CreatePrismBootstrapper () после base.DisplayRootView?Это не работает (NullPointerException на ServiceLocator, и я не уверен, будет ли это иметь смысл, так как я не очень знаком с библиотеками, которые вы используете, кроме Prism ...

Надеюсь, это поможет ...

...