Prism 7. Использование PrismApplication.CreateShell() с не оконным элементом управления
Я хотел бы обновить с 6,3 до 7.
Я, кажется, ударил блокпост.
При использовании класса PrismApplication в App.xaml CreateShell ожидает возвращаемый тип Window вместо предыдущего BootStrapper, который хотел DependencyObject.
Мой MainShell - это модифицированный Telerik RadWindow, который сам по себе является модифицированным System.Windows.Controls.HeaderedContentControl, и приведение к Window невозможно.
Есть ли способ обойти это, чтобы я мог использовать объект PrismApplication или мне нужно откатиться и использовать BootStrapper, как раньше?
2 ответа
я должен откатиться и использовать BootStrapper как раньше?
Бутстраппер все еще там. Он помечен как устаревший и может исчезнуть в будущей версии, но пока он есть, вы можете использовать его. По крайней мере, пока проблема с PrismApplicationBase
фиксированный. Вы должны создать проблему на GitHub для этого.
Редактировать:
Проблема уже была поднята и не будет исправлена ( 1413).
Я скопирую предложенный обходной путь из проблемы для справки:
protected override Window CreateShell()
{
return null;
}
protected override void OnInitialized()
{
var shellWindow = Container.Resolve<ShellWindow>();
shellWindow.Show();
MainWindow = shellWindow.ParentOfType<Window>();
// there lines was not executed because of null Shell - so must duplicate here. Originally called from PrismApplicationBase.Initialize
RegionManager.SetRegionManager(MainWindow, Container.Resolve<IRegionManager>());
RegionManager.UpdateRegions();
InitializeModules();
base.OnInitialized();
}
Чтобы сделать App.xaml.cs более похожим на обычный и сэкономить время, был создан следующий класс. Обратите внимание, что этот класс используетSystem.Reflection
. Он был создан со ссылкой на реализацию
PrismApplicationBase
, помог ответ Хаукингера.
/// <summary>
/// <br>Make sure that <see cref="Application.MainWindow"/> always returns null. Use <see cref="MainElement"/> instead.</br>
/// <br>Make sure that <see cref="CreateShell"/> is sealed. Use <see cref="CreateElement"/> instead.</br>
/// </summary>
public abstract class GeneralizedPrismApplication : PrismApplication
{
protected sealed override Window CreateShell()
{
return null;
}
/// <summary>
/// Creates the shell or main element of the application. Use this method instead of <see cref="CreateShell"/>.
/// </summary>
/// <returns>The shell of the application.</returns>
protected abstract FrameworkElement CreateElement();
/// <summary>
/// Gets or sets the main element of the application. Use this property instead of <see cref="Application.MainWindow"/>.
/// </summary>
public FrameworkElement MainElement { get; protected set; }
protected override void Initialize()
{
base.Initialize();
var shell = CreateElement();
if (shell != null)
{
var method = typeof(MvvmHelpers).GetMethod("AutowireViewModel", BindingFlags.Static | BindingFlags.NonPublic);
method.Invoke(null, new object[] { shell });
RegionManager.SetRegionManager(shell, this.Container.Resolve<IRegionManager>());
RegionManager.UpdateRegions();
InitializeShell(shell);
}
}
/// <summary>
/// Initializes the shell.
/// </summary>
/// <param name="shell"></param>
protected virtual void InitializeShell(FrameworkElement shell)
{
MainElement = shell;
}
/// <summary>
/// Do not override this method. Use <see cref="InitializeShell"/> instead.
/// </summary>
/// <param name="shell"></param>
protected sealed override void InitializeShell(Window shell)
{
;//Originally MainWindow = shell;
}
/// <summary>
/// Contains actions that should occur last.
/// </summary>
protected new virtual void OnInitialized()
{
;//Originally MainWindow.Show();
}
protected override void OnStartup(StartupEventArgs e)
{
this.ShutdownMode = ShutdownMode.OnExplicitShutdown;//Without this, the application will exit.
base.OnStartup(e);
}
}
Эту проблему можно решить просто
- Изготовление
App
наследовать этот класс в App.xaml - Замена
MainWindow
сMainElement
иCreateShell()
сCreateElement()
в App.xaml.cs.