Home > front end >  Two main windows loaded for WPF after adding legacy Prism
Two main windows loaded for WPF after adding legacy Prism

Time:01-18

I am having problem where my application is using very old Prism v4.x reference with added region manager and module. As result it shows two windows instead and they are linked together so doing any action on second shows in the first screen or the first screen is not fully loaded.

App.xaml.cs file:

using System;
using System.Windows;
namespace WpfTestApp
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        [STAThread]
        public static void Main(string[] args)
        {
            try
            {
                var app = new App();
                app.InitializeComponent();
                app.Run();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Fatal Exception occurred!");
            }
        }

        /// <inheritdoc />
        protected override void OnStartup(StartupEventArgs e)
        {
            try
            {
                base.OnStartup(e);
                
                var bootstrapper = new AppBootstrapper();
                bootstrapper.Run();

                base.OnStartup(e);
            }
            catch (Exception ex)
            {
                try
                {
                    MessageBox.Show(ex.ToString(), "App startup");
                }
                finally
                {
                    Current.Shutdown();
                }
            }
        }
    }
}

AppBootstrapper.cs file:

using System.Windows;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.UnityExtensions;
using Microsoft.Practices.ServiceLocation;

namespace WpfTestApp
{
    public class AppBootstrapper : UnityBootstrapper
    {
        protected override DependencyObject CreateShell()
        {
            InitializeModules();
            return ServiceLocator.Current.GetInstance<MainWindow>();
        }

        /// <summary>
        /// Runs the initialization steps to ensure that the shell is ready to be displayed. The shell application
        /// object is created and set as the main window of the application.
        /// </summary>
        protected override void InitializeShell()
        {
            base.InitializeShell();

            App.Current.MainWindow = (Window)Shell;
            App.Current.MainWindow.Show();
        }

        protected override void ConfigureModuleCatalog()
        {
            ModuleCatalog.AddModule(new ModuleInfo()
            {
                ModuleName = OutlookModule.NAME,
                ModuleType = typeof(OutlookModule).AssemblyQualifiedName,
                InitializationMode = InitializationMode.WhenAvailable
            });
        }
    }
}

Dummy module OutlookModule.cs file:

using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.Unity;

namespace WpfTestApp
{
    [Module(ModuleName = NAME)]
    public class OutlookModule : IModule
    {
        internal const string NAME = "OutlookModule";

        public OutlookModule(IUnityContainer container, IRegionManager regionManager)
        {
        }
        public void Initialize()
        {
        }
    }
}

A non standard WPF project file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup Label="Globals">
    <SccProjectName>SAK</SccProjectName>
    <SccProvider>SAK</SccProvider>
    <SccAuxPath>SAK</SccAuxPath>
    <SccLocalPath>SAK</SccLocalPath>
  </PropertyGroup>
  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
    <OutputType>WinExe</OutputType>
    <RootNamespace>SpreadsheetOwnerErrorSampleV3</RootNamespace>
    <AssemblyName>SpreadsheetOwnerErrorSampleV3</AssemblyName>
    <GenerateAssemblyInfo>False</GenerateAssemblyInfo>
    <ExpressionBlendVersion>12.0.51020.0</ExpressionBlendVersion>
    <OutputPath>..\bin\</OutputPath>
    <StartupObject>WpfTestApp.App</StartupObject>
    <EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
    <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
    <Prefer32Bit>true</Prefer32Bit>
    <DebugType>full</DebugType>
    <DebugSymbols>True</DebugSymbols>
  </PropertyGroup>
    <ItemGroup>
        <None Remove="WpfTestApp.csproj.vspscc" />
    </ItemGroup>
  <ItemGroup>
      <Page Include="App.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </Page>
    <Compile Include="App.xaml.cs">
      <DependentUpon>App.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="AppBootstrapper.cs" />
    <Compile Include="OutlookModule.cs" />
    <Page Include="MainWindow.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </Page>
    <Compile Include="MainWindow.xaml.cs">
      <DependentUpon>MainWindow.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <AppDesigner Include="Properties\" />
  </ItemGroup>

    <ItemGroup>
        <Reference Include="System" />
        <Reference Include="Microsoft.CSharp" />
        <Reference Include="System.Core" />
        <Reference Include="System.Xaml" />
        <Reference Include="UIAutomationProvider" />
        <Reference Include="WindowsBase" />
        <Reference Include="PresentationCore" />
        <Reference Include="PresentationFramework" />
    </ItemGroup>
    <ItemGroup>
        <PackageReference Include="Prism.Desktop.Net40" Version="4.1.1" />
        <PackageReference Include="Prism.UnityExtensions.Net40" Version="4.1.1" />
        <PackageReference Include="System.Windows.Interactivity.WPF" Version="2.0.20525" />
        <PackageReference Include="Unity" Version="2.1.505" />
    </ItemGroup>
  <ItemGroup>
    <BootstrapperPackage Include=".NETFramework,Version=v4.0">
      <Visible>False</Visible>
      <ProductName>Microsoft .NET Framework 4 (x86 and x64)</ProductName>
      <Install>true</Install>
    </BootstrapperPackage>
  </ItemGroup>
  <PropertyGroup>
    <LanguageTargets>$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Bin\Microsoft.CSharp.targets</LanguageTargets>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
  </PropertyGroup>
  <Target Name="WorkaroundForXAMLIntellisenseBuildIssue" AfterTargets="_CheckCompileDesignTimePrerequisite">
    <PropertyGroup>
      <BuildingProject>false</BuildingProject>
    </PropertyGroup>
  </Target>
  <Choose>
    <When Condition="'$(MSBuildProjectExtension)' != '.csproj' and '$(MSBuildProjectExtension)' != '.vbproj'">
      <PropertyGroup>
        <LanguageTargets Condition="Exists('$(MSBuildProjectDirectory)\$(AssemblyName).csproj')">$(MSBuildToolsPath)\Microsoft.CSharp.targets</LanguageTargets>
        <LanguageTargets Condition="Exists('$(MSBuildProjectDirectory)\$(AssemblyName).vbproj')">$(MSBuildToolsPath)\Microsoft.VisualBasic.targets</LanguageTargets>
      </PropertyGroup>
    </When>
  </Choose>
</Project>

Please help identify why two Windows are loaded when it should be only first one. I know that Prism used is outdated and we will upgrade in future. However, I need a working sample based on this version. All this legacy code was implemented based on fallowing articles a while ago:

http://www.infragistics.com/community/blogs/blagunas/archive/2012/09/13/xamdockmanager-a-prism-regionadapter.aspx http://brianlagunas.com/xamdockmanageran-updated-prism-region-adapter/ http://brianlagunas.com/xamdockmanager-prism-region-adapter-update-3/

Both windows loaded from App.xaml.cs Main method during app.Run() execution on CreateShell or later. However, this is required to work for application as per documentation: https://prismlibrary.com/docs/wpf/legacy/Initializing.html

Thanks in advance

CodePudding user response:

As @mm8 suggested the problem appeared to be in App.xaml itself which is by default injecting startup line with main view:

<Application x:Class="WpfTestApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfTestApp"

             !-> StartupUri="MainWindow.xaml">

    <Application.Resources>
         
    </Application.Resources>
</Application>
  •  Tags:  
  • Related