最终更新
我发现了问题。它与后台操纵无关。原因是我没有正确注册的资源字典。
我正在编写Windows Phone 8.1应用程序。因为我正在使用MVVMcross,所以我有一个经典的项目设置:一个包含ViewModels的便携式项目和一个包含Views的Windows Phone 8.1项目。
在某些情况下,我想从Backstack中删除一个页面,以便在单击后退按钮时显示删除页面之前的页面。
为了实现这种行为,我单独关注这个例子: https://edsnider.net/2014/04/07/clearing-windows-phone-nav-back-stack-in-mvvmcross/
除非我在应用程序中完成重新启动并再次重新打开应用程序,否则一切正常。在这种情况下,当我进行Backstack操作时,我得到一个COM异常:
The operation identifier is not valid.
The BackStack or ForwardStack cannot be changed while navigating.
问题:我的代码出了什么问题?
以下是相关的代码段:
方法DropPageAndShowViewModel在我的ViewModels的基类中定义。当我在ViewModel中调用此方法时会发生异常:
DropPageAndShowViewModel<TourdatenSummaryViewModel>(
new TourdatenSummaryViewModel.NavObject
{
Tournummer = _tour.Nummer
});
这是我的ViewModel的基类。 BaseViewModel派生自MvxViewModel。
public class BasePageViewModel : BaseViewModel
{
...
protected void DropPageAndShowViewModel<TViewModel>()
where TViewModel : BasePageViewModel
{
ShowViewModel<TViewModel>();
ChangePresentation(new DropCurrentBackStackEntryHint());
}
protected void DropPageAndShowViewModel<TViewModel>(object parameterValuesObject)
where TViewModel : BasePageViewModel
{
ShowViewModel<TViewModel>(parameterValuesObject);
ChangePresentation(new DropCurrentBackStackEntryHint());
}
}
正在进行Backstack操作的CustomViewPresenter:
public class DropCurrentBackStackEntryHint : MvxPresentationHint
{
}
public class CustomViewPresenter : MvxWindowsViewPresenter
{
private readonly IMvxWindowsFrame _rootFrame;
public CustomViewPresenter(IMvxWindowsFrame rootFrame) : base(rootFrame)
{
_rootFrame = rootFrame;
}
protected Frame RootFrame
{
get { return (Frame) _rootFrame.UnderlyingControl; }
}
public override void ChangePresentation(MvxPresentationHint hint)
{
if (hint is DropCurrentBackStackEntryHint)
{
if (RootFrame.BackStack.Any())
{
RootFrame.BackStack.RemoveAt(RootFrame.BackStackDepth - 1);
}
}
base.ChangePresentation(hint);
}
}
我在网上只发现了一个对此COM异常的引用,但对我没有帮助: https://github.com/Windows-XAML/Template10/issues/454
更新
我在这个处理程序中捕获未处理的异常:
void App_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
if (Debugger.IsAttached)
Debugger.Break();
e.Handled = true;
var message = "Error: \n\n" +
e.Message + "\n\n" +
e.Exception.HResult + "\n\n" +
e.Exception.Message + "\n\n" +
e.Exception.StackTrace;
new MessageDialog(message).ShowAsync();
}
当抛出异常时,我得到这个文本:
The operation identifier is not valid.
The BackStack or ForwardStack cannot be changed while navigating.
-2147020579
The operation identifier is not valid. (Exception from HRESULT: 0x800710DD)
HRESULT代码确实对我没有帮助:
C:\> err 0x800710DD
# as an HRESULT: Severity: FAILURE (1), Facility: 0x7, Code 0x10dd
# for hex 0x10dd / decimal 4317 :
ERROR_INVALID_OPERATION winerror.h
# The operation identifier is not valid.
# 1 matches found for "0x800710DD"
更新2
仅在应用程序在发布模式下构建时才会引发异常。在调试模式下不会发生。我必须重新启动设备才能实现它。
答案 0 :(得分:0)
我认为问题就是你这样说的方式。 首先,您调用ShowViewModel,然后您想从堆栈中删除页面。 听起来就像在发布模式下它会被同时调用,所以你得到这个消息。
0
在你的主持人那里:
public class DropCurrentBackStackEntryHint : MvxPresentationHint
{
public Type ViewModelType;
public DropCurrentBackStackEntryHint(Type viewModelType)
{
ViewModelType = viewModelType;
}
}
另一种解决方案,不是很好的方式: 当您始终要从堆栈中删除最后一页时,当您导航到此页面时,您可以从视图后面的代码中的Backstack中删除最后一页。
public override void ChangePresentation(MvxPresentationHint hint)
{
...
if (hint is DropCurrentBackStackEntryHint)
{
var dropHint = (DropCurrentBackStackEntryHint) hint;
var nativeView = Mvx.Resolve<IMvxViewsContainer>().GetViewType(dropHint.ViewModelType);
RootFrame.Navigate(nativeView, null);
// Perhaps you need here a await Task.Delay(200); here. You have to test the value
if (RootFrame.BackStack.Any() && RootFrame.BackStack.Count > 1)
{
RootFrame.BackStack.RemoveAt(RootFrame.BackStackDepth - 2);
}
}
...
}