Windows Phone 8.1 上的 MvvmCross 向后导航
MvvmCross backward navigation on Windows Phone 8.1
我有一个基于 Windows Phone Silverlight 8.1 MVVMCross 3.5.1 的应用程序,可以在视图之间完美地向前和向后导航。
为了向前导航,我使用
MvxViewModel.ShowViewModel()
API。这很好用。要向后导航,我只需使用 phone 上的后退按钮,这也很有效。
我正在制作一个 Windows Phone 8.1 等同于使用某些钱包功能的相同应用程序。向前导航按预期工作。但是,当我单击 phone 上的后退按钮时,应用程序退出。
这是 App.xaml.cs Windows Phone 8.1 应用程序的全部内容。
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public sealed partial class App : Application
{
private TransitionCollection transitions;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
this.Suspending += this.OnSuspending;
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used when the application is launched to open a specific file, to display
/// search results, and so forth.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
#if DEBUG
if (System.Diagnostics.Debugger.IsAttached)
{
this.DebugSettings.EnableFrameRateCounter = true;
}
#endif
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
// TODO: change this value to a cache size that is appropriate for your application
rootFrame.CacheSize = 1;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
// TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
var setup = new Setup(rootFrame);
setup.Initialize();
//// Removes the turnstile navigation for startup.
//if (rootFrame.ContentTransitions != null)
//{
// this.transitions = new TransitionCollection();
// foreach (var c in rootFrame.ContentTransitions)
// {
// this.transitions.Add(c);
// }
//}
//rootFrame.ContentTransitions = null;
//rootFrame.Navigated += this.RootFrame_FirstNavigated;
//// When the navigation stack isn't restored navigate to the first page,
//// configuring the new page by passing required information as a navigation
//// parameter
//if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))
//{
// throw new Exception("Failed to create initial page");
//}
var starter = Cirrious.CrossCore.Mvx.Resolve<Cirrious.MvvmCross.ViewModels.IMvxAppStart>();
starter.Start();
}
// Ensure the current window is active
Window.Current.Activate();
}
/// <summary>
/// Restores the content transitions after the app has launched.
/// </summary>
/// <param name="sender">The object where the handler is attached.</param>
/// <param name="e">Details about the navigation event.</param>
private void RootFrame_FirstNavigated(object sender, NavigationEventArgs e)
{
var rootFrame = sender as Frame;
rootFrame.ContentTransitions = this.transitions ?? new TransitionCollection() { new NavigationThemeTransition() };
rootFrame.Navigated -= this.RootFrame_FirstNavigated;
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
// TODO: Save application state and stop any background activity
deferral.Complete();
}
}
我错过了什么?
Windows Phone 8.1 对您的导航进行了一些处理,使其无法正常工作。
这些问题包含有关此主题的大量信息:
https://github.com/MvvmCross/MvvmCross/pull/760
https://github.com/MvvmCross/MvvmCross/issues/1018
https://gist.github.com/Cheesebaron/3d33daf4b76dc091e26e
您可以用作基础 class 的代码是:
public abstract class BaseView<T> : MvxWindowsPage<T> where T : MvxViewModel
{
private ICommand _goBackCommand;
public ICommand GoBackCommand
{
get { return _goBackCommand ?? (_goBackCommand = new MvxCommand(GoBack, CanGoBack)); }
set { _goBackCommand = value; }
}
protected BaseView()
{
NavigationCacheMode = NavigationCacheMode.Required;
Loaded += (s, e) => {
HardwareButtons.BackPressed += HardwareButtonsBackPressed;
};
Unloaded += (s, e) => {
HardwareButtons.BackPressed -= HardwareButtonsBackPressed;
};
}
private void HardwareButtonsBackPressed(object sender, BackPressedEventArgs e)
{
if (GoBackCommand.CanExecute(null))
{
e.Handled = true;
GoBackCommand.Execute(null);
}
}
public virtual void GoBack()
{
if (Frame != null && Frame.CanGoBack) Frame.GoBack();
}
public virtual bool CanGoBack()
{
return Frame != null && Frame.CanGoBack;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.New)
ViewModel = null;
base.OnNavigatedTo(e);
}
}
我有一个基于 Windows Phone Silverlight 8.1 MVVMCross 3.5.1 的应用程序,可以在视图之间完美地向前和向后导航。
为了向前导航,我使用
MvxViewModel.ShowViewModel()
API。这很好用。要向后导航,我只需使用 phone 上的后退按钮,这也很有效。
我正在制作一个 Windows Phone 8.1 等同于使用某些钱包功能的相同应用程序。向前导航按预期工作。但是,当我单击 phone 上的后退按钮时,应用程序退出。
这是 App.xaml.cs Windows Phone 8.1 应用程序的全部内容。
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public sealed partial class App : Application
{
private TransitionCollection transitions;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
this.Suspending += this.OnSuspending;
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used when the application is launched to open a specific file, to display
/// search results, and so forth.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
#if DEBUG
if (System.Diagnostics.Debugger.IsAttached)
{
this.DebugSettings.EnableFrameRateCounter = true;
}
#endif
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
// TODO: change this value to a cache size that is appropriate for your application
rootFrame.CacheSize = 1;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
// TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
var setup = new Setup(rootFrame);
setup.Initialize();
//// Removes the turnstile navigation for startup.
//if (rootFrame.ContentTransitions != null)
//{
// this.transitions = new TransitionCollection();
// foreach (var c in rootFrame.ContentTransitions)
// {
// this.transitions.Add(c);
// }
//}
//rootFrame.ContentTransitions = null;
//rootFrame.Navigated += this.RootFrame_FirstNavigated;
//// When the navigation stack isn't restored navigate to the first page,
//// configuring the new page by passing required information as a navigation
//// parameter
//if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))
//{
// throw new Exception("Failed to create initial page");
//}
var starter = Cirrious.CrossCore.Mvx.Resolve<Cirrious.MvvmCross.ViewModels.IMvxAppStart>();
starter.Start();
}
// Ensure the current window is active
Window.Current.Activate();
}
/// <summary>
/// Restores the content transitions after the app has launched.
/// </summary>
/// <param name="sender">The object where the handler is attached.</param>
/// <param name="e">Details about the navigation event.</param>
private void RootFrame_FirstNavigated(object sender, NavigationEventArgs e)
{
var rootFrame = sender as Frame;
rootFrame.ContentTransitions = this.transitions ?? new TransitionCollection() { new NavigationThemeTransition() };
rootFrame.Navigated -= this.RootFrame_FirstNavigated;
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
// TODO: Save application state and stop any background activity
deferral.Complete();
}
}
我错过了什么?
Windows Phone 8.1 对您的导航进行了一些处理,使其无法正常工作。
这些问题包含有关此主题的大量信息: https://github.com/MvvmCross/MvvmCross/pull/760 https://github.com/MvvmCross/MvvmCross/issues/1018 https://gist.github.com/Cheesebaron/3d33daf4b76dc091e26e
您可以用作基础 class 的代码是:
public abstract class BaseView<T> : MvxWindowsPage<T> where T : MvxViewModel
{
private ICommand _goBackCommand;
public ICommand GoBackCommand
{
get { return _goBackCommand ?? (_goBackCommand = new MvxCommand(GoBack, CanGoBack)); }
set { _goBackCommand = value; }
}
protected BaseView()
{
NavigationCacheMode = NavigationCacheMode.Required;
Loaded += (s, e) => {
HardwareButtons.BackPressed += HardwareButtonsBackPressed;
};
Unloaded += (s, e) => {
HardwareButtons.BackPressed -= HardwareButtonsBackPressed;
};
}
private void HardwareButtonsBackPressed(object sender, BackPressedEventArgs e)
{
if (GoBackCommand.CanExecute(null))
{
e.Handled = true;
GoBackCommand.Execute(null);
}
}
public virtual void GoBack()
{
if (Frame != null && Frame.CanGoBack) Frame.GoBack();
}
public virtual bool CanGoBack()
{
return Frame != null && Frame.CanGoBack;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.New)
ViewModel = null;
base.OnNavigatedTo(e);
}
}