0

我注册到我的页面的 OnSizeChanged 事件,如下所示:

private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
    ApplicationViewState myViewState = ApplicationView.Value;
    if (myViewState == ApplicationViewState.Snapped)
    {
         Windows.UI.ViewManagement.ApplicationView.TryUnsnap();                
    }
}  

当用户尝试(手动....)将其调整为快照视图时,我很想将应用程序视图设置为填充/纵向状态。但是 TryUnsnap 方法失败并且它保持在捕捉状态......

帮助!

谢谢。

4

2 回答 2

3

要了解 TryUnsnap(),我们需要了解两种类型的 Windows 8 事件:

  1. 程序化事件

    程序化事件不需要用户做任何事情。例如 Page 的 Loaded 事件或 Timer 的 Tick 事件。

  2. 用户发起的事件

    用户发起的事件需要用户做某事。例如 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 中程序化事件和用户启动事件之间区别的开发人员来说是令人沮丧的。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

这会让你得到你想要的,但它带来了一个重要的观点。看看在 TryUnsnap 之后状态如何保持“Snapped”?视觉状态从一个到另一个的转换不是同步事件。呼吁改变需要不可预测的时间。这可能是通过发送邮件完成的,但我必须检查一下才能确定。

说了这么多,状态确实发生了变化。并且,在更改后引发 CurrentStateChanged 事件,您可以处理新的 Snapped 状态。顺便说一句,是否有另一个快照应用程序并不重要,这两种方式都可以。

MSDN 文档说它只在前台工作时才有效。这是非常愚蠢的,因为用户交互不能在后台应用程序上发生,并且后台应用程序无论如何都会暂停其线程。但是,为了对 MSDN 公平起见,当您的应用程序在后台运行时,此 API 不起作用——不管它值多少钱。

我希望这有助于清除它。

现在回答你的问题:

你想从 Snapped 到 Portrait 吗?当然,在 Portrait 中,Snapped 是不可能的,因此您无法编写代码。您想在应用程序被捕捉后立即从 Snapped 变为 Filled。从 Snapped 操作引发的事件是编程事件。因此,您必须先诱使用户在您的 UI 中做某事。所以,不,你不能做你所要求的。在用户以某种方式与您的应用程序交互(如按钮单击事件)之前,您不能 Unsnap() 。

哦,如果你想引用我的所有代码,这里是 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);
}

祝你有美好的一天,祝你好运!

于 2013-05-07T19:40:12.653 回答
0
            var CurrentSnappedState = ApplicationView.Value;
            if (CurrentSnappedState == ApplicationViewState.Snapped && !ApplicationView.TryUnsnap())
            {
                return;
            }

应该做的伎俩。请记住,您仍然可以捕捉页面,但是当您尝试在捕捉的页面中执行任何操作时,您将被重定向到完整视图。

于 2013-05-07T14:25:32.220 回答