我注册了我的Page的OnSizeChanged事件,如下:
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
ApplicationViewState myViewState = ApplicationView.Value;
if (myViewState == ApplicationViewState.Snapped)
{
Windows.UI.ViewManagement.ApplicationView.TryUnsnap();
}
}
当用户尝试(手动....)将其大小调整为捕捉视图时,我正在设置应用程序视图为Filled / Portrait状态。 但TryUnsnap方法失败并且它处于捕捉状态......
帮助!
感谢。
答案 0 :(得分:3)
要了解TryUnsnap(),我们需要了解两种类型的Windows 8事件:
计划活动
程序化事件不要求用户做任何事情。例如,Page的Loaded事件或Timer的Tick事件。
用户启动的活动
用户启动的事件要求用户执行某些操作。例如Button的Click事件或Control的Tapped事件。
重要部分
根据事件的类型,只能调用某些Windows 8 API。例如,添加辅助磁贴。并且(正如您可能已经猜到的那样)取消应用程序。
这意味着您可以从程序化事件中调用所有这些API,但它们永远不会提供您想要的结果。在StateChanged事件中解除绑定,因此会失败。在Button.Click事件中取消禁用,因此会成功。
此行为背后的基本原理是用户体验。如果应用程序可以在没有用户交互的情况下更改用户的'方向',那么应用程序的行为将变得混乱和不可预测。 Windows 8是一个支持用户的操作系统。当你发现开发者的“约束”时,99%的时间背后都是这种哲学。
让我演示:
如果您附加了StateChanged事件,您的代码将如下所示:
this.ApplicationViewStates.CurrentStateChanged += (s, args) =>
{
System.Diagnostics.Debug.WriteLine("After StateChanged: {0}", this.ApplicationViewStates.CurrentState.Name);
if (this.ApplicationViewStates.CurrentState == this.Snapped)
{
System.Diagnostics.Debug.WriteLine("Before Unsnap: {0}", this.ApplicationViewStates.CurrentState.Name);
Unsnap();
}
};
但是,结果输出(在调试器中)将如下所示:
After StateChanged: FullScreenLandscape
After StateChanged: Snapped
Before Unsnap: Snapped
After TryUnsnap: Snapped
对于不了解Windows 8中 programmatic 和用户启动的事件之间差异的开发人员来说,这是令人沮丧的。当API时,API似乎“无效”事实上,它完美地运作。只是不喜欢他们想要它。
如果您附加了Click事件,您的代码将如下所示:
MyButton.Click += (s, args) =>
{
System.Diagnostics.Debug.WriteLine("After Button.Click: {0}", this.ApplicationViewStates.CurrentState.Name);
if (this.ApplicationViewStates.CurrentState == this.Snapped)
{
System.Diagnostics.Debug.WriteLine("Before Unsnap: {0}", this.ApplicationViewStates.CurrentState.Name);
Unsnap();
}
};
然后,结果输出如下所示:
After Button.Click: Snapped
Before Unsnap: Snapped
After TryUnsnap: Snapped
After StateChanged: FullScreenLandscape
这可以让你得到你想要的东西,但它提出了一个重要的观点。看看After TryUnsnap状态REMAINS“Snapped”后怎么样?视觉状态从一个转换到另一个不是同步事件。呼吁改变需要不可预测的时间。 这可能是通过发送邮件完成的,但我必须检查以确定。
说了这么多,状态确实改变了。并且,在更改之后,将引发CurrentStateChanged事件,您可以处理新的Snapped状态。顺便说一下,如果有另一个抢购的应用程序无关紧要,这种方式都可以。
MSDN文档说它只有在前台时才有效。这是非常愚蠢的,因为用户交互不能在后台应用程序上发生,并且后台应用程序无论如何都要暂停其线程。但是,为了公平对待MSDN,当您的应用程序处于后台时,此API不起作用 - 无论值得多少。
我希望这有助于澄清它。
现在问你的问题:
你想从Snapped转到Portrait吗?当然在Portrait中,Snapped是不可能的,所以这不是你编码的可能性。一旦应用程序被捕捉,您希望从Snapped变为Filled。 Snapped动作引发的事件是一个程序性事件。因此,您必须首先引诱用户在您的UI中执行某些操作。所以,不,你不能做你要求的。在用户以某种方式与您的应用交互之前(例如按钮点击事件),您不能解除()。
哦,如果你想引用我的所有代码,这里是Unsnap()方法。我没有做任何特别的事,但你可能会感兴趣:
void Unsnap()
{
if (Windows.UI.ViewManagement.ApplicationView.TryUnsnap())
// successfully unsnapped
System.Diagnostics.Debug.WriteLine("After TryUnsnap: {0}", this.ApplicationViewStates.CurrentState.Name);
else
// un-successfully unsnapped
System.Diagnostics.Debug.WriteLine("After TryUnsnap: {0}", this.ApplicationViewStates.CurrentState.Name);
}
度过美好的一天,祝你好运!
答案 1 :(得分:0)
var CurrentSnappedState = ApplicationView.Value;
if (CurrentSnappedState == ApplicationViewState.Snapped && !ApplicationView.TryUnsnap())
{
return;
}
应该做的伎俩。请记住,您仍然可以对页面进行捕捉,但是当您尝试在捕捉的页面中执行任何操作时,您将被重定向到全视图。