ResourceDictionary无法加载,因为覆盖OnStartup
问题描述:
我在做使用MVVM的wpf项目。 我在App.xaml.cs文件中使用override OnStartup,因为我使用NavigationService clas以在页面之间导航。 问题是在App.xaml文件中找到的ResourceDictionary未加载,因此我无法使用Locator。这里是我的代码 -ResourceDictionary无法加载,因为覆盖OnStartup
App.xaml文件:
<Application x:Class="TalkBackClient2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" d1p1:Ignorable="d" xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Application.Resources>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:vm="clr-namespace:TalkBackClient2.ViewModel" />
</ResourceDictionary>
App.xaml.cs文件:
public partial class App : Application
{
Navigation.NavigationService nav;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
nav = new Navigation.NavigationService();
}
}
的NavigationService文件:
namespace TalkBackClient2.Navigation
{
class NavigationService
{
#region fields
private const WindowsEnum FirstScreen = WindowsEnum.LoginScreen;
private MainWindow mainWindow = new MainWindow();
private LoginScreen loginScreen = new LoginScreen();
private RegistrationScreen registrationScreen = new RegistrationScreen();
private ChatScreen chatViewModel = new ChatScreen();
private GameScreen gameScreen = new GameScreen();
#endregion
public NavigationService()
{
Messenger.Default.Register<NavMessage>(this, navToPage);
openWindow(FirstScreen);
}
private void navToPage(NavMessage navMessage)
{
if (navMessage.NavFrom != WindowsEnum.MainWindow)
{
CloseWindow(navMessage.NavFrom);
}
openWindow(navMessage.NavToPage);
}
private void CloseWindow(WindowsEnum navFrom)
{
switch (navFrom)
{
case WindowsEnum.LoginScreen:
loginScreen.Hide();
break;
case WindowsEnum.GameScreen:
gameScreen.Hide();
break;
case WindowsEnum.RegistrationScreen:
registrationScreen.Hide();
break;
case WindowsEnum.ChatScreen:
chatViewModel.Hide();
break;
case WindowsEnum.MainWindow:
mainWindow.Hide();
break;
default:
break;
}
}
private void openWindow(WindowsEnum navTo)
{
switch (navTo)
{
case WindowsEnum.RegistrationScreen:
if (registrationScreen == null)
{
registrationScreen = new RegistrationScreen();
}
registrationScreen.Show();
break;
case WindowsEnum.GameScreen:
if (gameScreen == null)
{
gameScreen = new GameScreen();
}
gameScreen.Show();
break;
case WindowsEnum.ChatScreen:
if (chatViewModel == null)
{
chatViewModel = new ChatScreen();
}
chatViewModel.Show();
break;
case WindowsEnum.MainWindow:
mainWindow = new MainWindow();
var dataContext = (MainWindowViewModel)mainWindow.DataContext;
dataContext.Greeting = $"Greeting {Util.LoggedInUser.UserName}";
mainWindow.Show();
break;
case WindowsEnum.LoginScreen:
default:
if (loginScreen == null)
{
loginScreen = new LoginScreen();
}
loginScreen.Show();
break;
}
}
}
}
答
HAV e您试图在app标签中定义名称空间xmlns:vm而不是在viewModel标签中?
答
我只是对同样的问题感到困惑。在玩了一段时间后(使用.NET 4.5.2),似乎有两种可能的解决方案(还有更多的困惑,因为我还没有找到背景为什么他们会工作)。
第一个解决方案:处理启动事件,而不是覆盖OnStartup。 显然,在事件处理程序中打开窗口时,ResourceDictionary会在窗口之前加载并可用。
解决方法二(我一个解释真的很好奇):把你的资源,资源字典是你的应用程序资源的合并资源字典里面。在这种情况下,即使覆盖OnStartup,合并的ResourceDictionary中的资源也可用于您的窗口。
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
[... your resource here ...]
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
也许任何人都可以提供关于WPF应用程序启动机制的更多细节,可以清除它。
你的意思是写 ? 如果是这样,就没有应用程序标签,因为我可以看到.. –
nop i meean''然后在您使用标签的资源中' ' –
我尝试了你的建议,但我得到一个运行时错误 - “找不到名为'locator'的资源。资源名称是区分大小写的。“虽然它显然有resourse(intellisense认出它) 我认为,确认它覆盖OnStartup碰巧之前资源被加载 –