C# 如何从其他页面(Windows Template Studio)初始化ShellView

C# 如何从其他页面(Windows Template Studio)初始化ShellView,c#,uwp,prism,navigationview,windows-template-studio,C#,Uwp,Prism,Navigationview,Windows Template Studio,Windows模板工作室: 我用导航窗格类型和棱镜模式创建了一个项目,我有设置和一些页面 以下是App.xaml.cs: [Windows.UI.Xaml.Data.Bindable] public sealed partial class App : PrismUnityApplication { public App() { InitializeComponent(); } protected override void ConfigureC

Windows模板工作室:

我用导航窗格类型和棱镜模式创建了一个项目,我有设置和一些页面

以下是App.xaml.cs:

[Windows.UI.Xaml.Data.Bindable]
public sealed partial class App : PrismUnityApplication
{
    public App()
    {
        InitializeComponent();
    }

    protected override void ConfigureContainer()
    {
        // register a singleton using Container.RegisterType<IInterface, Type>(new ContainerControlledLifetimeManager());
        base.ConfigureContainer();
        Container.RegisterInstance<IResourceLoader>(new ResourceLoaderAdapter(new ResourceLoader()));
        Container.RegisterType<ISampleDataService, SampleDataService>();
    }

    protected override async Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
    {
        await LaunchApplicationAsync(PageTokens.MainPage, null);
    }

    private async Task LaunchApplicationAsync(string page, object launchParam)
    {
        await ThemeSelectorService.SetRequestedThemeAsync();
        NavigationService.Navigate(page, launchParam);
        Window.Current.Activate();
    }

    protected override async Task OnActivateApplicationAsync(IActivatedEventArgs args)
    {
        await Task.CompletedTask;
    }

    protected override async Task OnInitializeAsync(IActivatedEventArgs args)
    {
        await base.OnInitializeAsync(args);
        await ThemeSelectorService.InitializeAsync().ConfigureAwait(false);

        //We are remapping the default ViewNamePage and ViewNamePageViewModel naming to ViewNamePage and ViewNameViewModel to
        //gain better code reuse with other frameworks and pages within Windows Template Studio
        ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
        {
            var viewModelTypeName = string.Format(CultureInfo.InvariantCulture, "App1.ViewModels.{0}ViewModel, App1", viewType.Name.Substring(0, viewType.Name.Length - 4));
            return Type.GetType(viewModelTypeName);
        });
    }

    protected override IDeviceGestureService OnCreateDeviceGestureService()
    {
        var service = base.OnCreateDeviceGestureService();
        service.UseTitleBarBackButton = false;
        return service;
    }

    public void SetNavigationFrame(Frame frame)
    {
        var sessionStateService = Container.Resolve<ISessionStateService>();
        CreateNavigationService(new FrameFacadeAdapter(frame), sessionStateService);
    }

    protected override UIElement CreateShell(Frame rootFrame)
    {
        var shell = Container.Resolve<ShellPage>();
        shell.SetRootFrame(rootFrame);
        return shell;
    }
}
protected override void ConfigureViewModelLocator()
    {
        base.ConfigureViewModelLocator();

        ViewModelLocationProvider.Register<SignInPage, ViewModels.SignInPageViewModel>();
    }
并删除了:

protected override UIElement CreateShell(Frame rootFrame)
    {
        var shell = Container.Resolve<ShellPage>();
        shell.SetRootFrame(rootFrame);
        return shell;
    }
受保护的重写UIElement CreateShell(框架根框架)
{
var shell=Container.Resolve();
shell.SetRootFrame(rootFrame);
返回壳;
}
现在我的应用程序启动页面是我的登录页面,我在该页面上有登录按钮,并从我的viewmodel delegatecommand绑定了命令,但它无法找到我的viewmodel(ViewModelLocator.AutoWireViewModel=“True”),因此我在我的app.xaml.cs上添加了以下内容:

[Windows.UI.Xaml.Data.Bindable]
public sealed partial class App : PrismUnityApplication
{
    public App()
    {
        InitializeComponent();
    }

    protected override void ConfigureContainer()
    {
        // register a singleton using Container.RegisterType<IInterface, Type>(new ContainerControlledLifetimeManager());
        base.ConfigureContainer();
        Container.RegisterInstance<IResourceLoader>(new ResourceLoaderAdapter(new ResourceLoader()));
        Container.RegisterType<ISampleDataService, SampleDataService>();
    }

    protected override async Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
    {
        await LaunchApplicationAsync(PageTokens.MainPage, null);
    }

    private async Task LaunchApplicationAsync(string page, object launchParam)
    {
        await ThemeSelectorService.SetRequestedThemeAsync();
        NavigationService.Navigate(page, launchParam);
        Window.Current.Activate();
    }

    protected override async Task OnActivateApplicationAsync(IActivatedEventArgs args)
    {
        await Task.CompletedTask;
    }

    protected override async Task OnInitializeAsync(IActivatedEventArgs args)
    {
        await base.OnInitializeAsync(args);
        await ThemeSelectorService.InitializeAsync().ConfigureAwait(false);

        //We are remapping the default ViewNamePage and ViewNamePageViewModel naming to ViewNamePage and ViewNameViewModel to
        //gain better code reuse with other frameworks and pages within Windows Template Studio
        ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
        {
            var viewModelTypeName = string.Format(CultureInfo.InvariantCulture, "App1.ViewModels.{0}ViewModel, App1", viewType.Name.Substring(0, viewType.Name.Length - 4));
            return Type.GetType(viewModelTypeName);
        });
    }

    protected override IDeviceGestureService OnCreateDeviceGestureService()
    {
        var service = base.OnCreateDeviceGestureService();
        service.UseTitleBarBackButton = false;
        return service;
    }

    public void SetNavigationFrame(Frame frame)
    {
        var sessionStateService = Container.Resolve<ISessionStateService>();
        CreateNavigationService(new FrameFacadeAdapter(frame), sessionStateService);
    }

    protected override UIElement CreateShell(Frame rootFrame)
    {
        var shell = Container.Resolve<ShellPage>();
        shell.SetRootFrame(rootFrame);
        return shell;
    }
}
protected override void ConfigureViewModelLocator()
    {
        base.ConfigureViewModelLocator();

        ViewModelLocationProvider.Register<SignInPage, ViewModels.SignInPageViewModel>();
    }
protected override void ConfigureViewModelLocator()
{
base.ConfigureViewModelLocator();
ViewModelLocationProvider.Register();
}
问题1:为什么即使我的viewmodel与自动创建的页面具有相同的名称空间,它也无法找到它

现在,button命令将导航到ShellPage,因此每当我单击该按钮时,它都将导航到ShellPage,但框架未正确初始化,因此当我尝试导航到任何页面时,会出现空引用错误


问题2:如何在导航页面上初始化ShellPage?

问题可能在于您的命名

SigningPageViewModel
更改为
SigningViewModel

受保护的重写异步任务OnInitializeAsync(IActivatedEventArgs args)
{
wait base.OnInitializeAsync(args);
//我们正在将默认的ViewNamePage和ViewNamePageViewModel命名重新映射到ViewNamePage,并将ViewNameViewModel映射到
//在Windows Template Studio中与其他框架和页面实现更好的代码重用
ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType)=>
{
var viewModelTypeName=string.Format(CultureInfo.InvariantCulture,“App1.ViewModels.{0}ViewModel,App1”,viewmype.Name.Substring(0,viewmype.Name.Length-4));
返回类型.GetType(viewModelTypeName);
});
}
请注意,此函数用于注册当前页面的ViewModel。根据相应的命名约定,如果页面的名称是
{name}Page.xaml
,那么ViewModel就是
{name}ViewModel.cs


更新

如何在导航页面上初始化ShellPage

坦率地说,这种行为不符合当前的体系结构。因为默认情况下,应用程序只有一个rootFrame,但是由于您删除了CreateShell方法的覆盖,它必然会引入第二个帧,这将导致未知错误

如果您坚持,我在这里提供了一个方法,但是当软件关闭时,它将无法正确保存
会话状态

App.xaml.cs

公共静态应用实例;
公共应用程序()
{
初始化组件();
实例=此;
}
signipage.xaml.cs

请收听xaml中的
登录按钮\u Click
事件

private void SignInButton_单击(对象发送者,Windows.UI.Xaml.RoutedEventArgs e)
{
var rootFrame=Window.Current.Content作为框架;
var frame=新帧();
App.Instance.SetNavigationFrame(框架);
导航(typeof(ShellPage),frame);
}
ShellPage.xaml.cs

受保护的覆盖无效OnNavigatedTo(NavigationEventArgs e)
{
如果(e.参数为帧)
{
SetRootFrame(frame);
框架导航(类型(主页));
}
}

问候。

哦,是的,这是命名lol,谢谢你,因为问题2,我还不能把这个标记为答案。嗨,很抱歉我错过了。我更新了我的答案,请检查。不用担心,谢谢。它成功了,但是有更好的方法来实现这一点吗?或者应用mvvm模式?恐怕不行。当您选择使用
登录页面
作为启动页面时,应用程序结构已更改。就像一匹跑出跑道的马,没有好办法把它拉回来。我建议您考虑一个更适合当前体系结构的登录方法。哦,好吧,登录方法是什么意思?