添加遗留 Prism 后为 WPF 加载的两个主要 windows
Two main windows loaded for WPF after adding legacy Prism
我的应用程序使用非常旧的 Prism v4.x 引用并添加了区域管理器和模块,我遇到了问题。结果,它显示了两个 windows,并且它们链接在一起,因此在第一个屏幕中的第二个节目上执行任何操作,或者第一个屏幕未完全加载。
App.xaml.cs 文件:
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 文件:
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
});
}
}
}
虚拟模块OutlookModule.cs 文件:
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()
{
}
}
}
非标准 WPF 项目文件:
<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 %28x86 and x64%29</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>
请帮助确定为什么加载了两个 Windows 而它应该只是第一个。我知道使用的 Prism 已经过时,我们将来会升级。但是,我需要一个基于此版本的工作示例。所有这些遗留代码都是根据前一段时间的休闲文章实现的:
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/
两者 windows 在 app.Run() 在 CreateShell 或之后执行期间从 App.xaml.cs Main 方法加载。但是,根据文档,这对于应用程序是必需的:
https://prismlibrary.com/docs/wpf/legacy/Initializing.html
提前致谢
正如@mm8 所建议的那样,问题似乎出在 App.xaml 本身,它默认在主视图中注入启动行:
<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>
我的应用程序使用非常旧的 Prism v4.x 引用并添加了区域管理器和模块,我遇到了问题。结果,它显示了两个 windows,并且它们链接在一起,因此在第一个屏幕中的第二个节目上执行任何操作,或者第一个屏幕未完全加载。
App.xaml.cs 文件:
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 文件:
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
});
}
}
}
虚拟模块OutlookModule.cs 文件:
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()
{
}
}
}
非标准 WPF 项目文件:
<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 %28x86 and x64%29</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>
请帮助确定为什么加载了两个 Windows 而它应该只是第一个。我知道使用的 Prism 已经过时,我们将来会升级。但是,我需要一个基于此版本的工作示例。所有这些遗留代码都是根据前一段时间的休闲文章实现的:
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/
两者 windows 在 app.Run() 在 CreateShell 或之后执行期间从 App.xaml.cs Main 方法加载。但是,根据文档,这对于应用程序是必需的: https://prismlibrary.com/docs/wpf/legacy/Initializing.html
提前致谢
正如@mm8 所建议的那样,问题似乎出在 App.xaml 本身,它默认在主视图中注入启动行:
<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>