使用 MvvmCross 在 UWP 应用程序中打开新的 windows

Open new windows in UWP app with MvvmCross

我尝试在我的 UWP 应用程序的 new window 中打开一个页面。 MvvmCross 提供的 IMvxNavigationService 是否可行?现在它只替换当前 window.

中的页面

导航流程

ViewModel

public class MyViewModel: MvxViewModel
{
    private readonly IMvxNavigationService _navigationService;

    public MyViewModel(IMvxNavigationService navigationService)
    {
        _navigationService = navigationService;
    }

    public MvxCommand MyCommand { get; set; }

    public override void Prepare()
    {
        base.Prepare();
        MyCommand = new MvxCommand<>(MyEvent);
    }

    private void MyEvent()
    {
        _navigationService.Navigate<OtherViewModel>();
    }
}

如果你打算在UWP中新开window,推荐更传统的方式

public static async Task<bool> TryOpenNewWindow(Type page)
{
    CoreApplicationView newView = CoreApplication.CreateNewView();
    int newViewId = 0;
    await newView.Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
    {
        Frame frame = new Frame();
        frame.Navigate(page);
        Window.Current.Content = frame;
        // You have to activate the window in order to show it later.
        Window.Current.Activate();

        newViewId = ApplicationView.GetForCurrentView().Id;
    });
    bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
    return viewShown;
}

用法

bool isShow = await TryOpenNewWindow(typeof(MyPage));

使用MVVMCross时,只在当前window中导航而没有在新window中导航的原因可能是您没有注册新window的Frame。

如果您遵循 documentation,您可能需要在创建新 window 时重新注册 public class Setup: MvxWindowsSetup

此致。

我现在意识到我可以实现自定义演示器并使用新的 AppWindow

MvxWindowPresentationAttribute.cs

public class MvxWindowPresentationAttribute : MvxBasePresentationAttribute
{
}

CustomMvxWindowsViewPresenter.cs

public class CustomMvxWindowsViewPresenter : MvxWindowsViewPresenter
{
    public CustomMvxWindowsViewPresenter(IMvxWindowsFrame rootFrame) : base(rootFrame)
    {
    }

    public override void RegisterAttributeTypes()
    {
        base.RegisterAttributeTypes();
        AttributeTypesToActionsDictionary.Register<MvxWindowPresentationAttribute>(ShowWindow, CloseWindow);
    }

    private Task<bool> CloseWindow(IMvxViewModel viewModel, MvxWindowPresentationAttribute attribute)
    {
        return base.ClosePage(viewModel, attribute);
    }

    private Task<bool> ShowWindow(Type viewType, MvxWindowPresentationAttribute attribute,
        MvxViewModelRequest request)
    {
        try
        {
            return Task.Run(async () =>
            {
                var requestText = GetRequestText(request);
                var viewsContainer = Mvx.IoCProvider.Resolve<IMvxViewsContainer>();

                await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High,
                    async () => {
                        var appWindow = await AppWindow.TryCreateAsync();
                        var appWindowContentFrame = new Frame();
                        appWindowContentFrame.Navigate(viewType, requestText);
                        ElementCompositionPreview.SetAppWindowContent(appWindow, appWindowContentFrame);
                        await appWindow.TryShowAsync();
                        HandleBackButtonVisibility();
                    });
                return true;
            });
        }
        catch (Exception exception)
        {
            return Task.FromResult(false);
        }
    }
}

Setup.cs

protected override IMvxWindowsViewPresenter CreateViewPresenter(IMvxWindowsFrame rootFrame)
{
    return new CustomMvxWindowsViewPresenter(rootFrame);
}

唯一剩下要做的就是用创建的属性注释您的视图 MvxWindowPresentation

OtherView.xaml.cs

[MvxWindowPresentation]
public sealed partial class OtherView : MvxWindowsPage 
{
   // ...
}