0

次のように、自分の Page の 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() を理解するには、2 種類の 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 後、状態が「スナップ済み」のままになる方法をご覧ください。Visual State の遷移は、同期イベントではありません。変更の呼び出しには、予測できないほどの時間がかかります。おそらく発送ポストで済んでいると思いますが、念のため確認する必要があります。

そうは言っても、状態変化します。また、変更後に 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 に答える