繁体   English   中英

Prism 7. 将 PrismApplication.CreateShell() 与非 Window 控件一起使用

[英]Prism 7. Using PrismApplication.CreateShell() with a non Window control

我想从 6.3 更新到 7。

我似乎遇到了障碍。

当在 App.xaml 中使用 PrismApplication class 时,CreateShell 期望返回类型 Window 而不是之前需要 DependencyObject 的 BootStrapper。

我的 MainShell 是经过修改的 Telerik RadWindow,它本身是经过修改的 System.Windows.Controls.HeaderedContentControl 并且无法转换为 Window。

有没有办法解决这个问题,这样我就可以使用 PrismApplication object 或者我必须回滚并像以前一样使用 BootStrapper?

我是否必须像以前一样回滚并使用 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更像一个普通的,也为了节省时间,创建了如下class。 请注意,此 class 使用System.Reflection 它是在 Haukinger 的回答的帮助下,参考 PrismApplicationBase 的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);
    }
}

这个问题可以简单地解决

  1. App在App.xaml中继承这个class
  2. 在 App.xaml.cs 中用MainElement替换MainWindow ,用CreateElement()替换CreateShell()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM