2

他の誰かが同じ苦痛に苦しむ必要がないように、これを質問と答えとして文書化するだけです。

iPhoneでスワイプするのと同じように、ページをアニメーション化するWPFアプリケーションがあります。ページの1つにWebBrowserを含める必要があるまでは、すべて問題ありませんでした。アニメーションにはまったく反応しませんでした。スライドインするはずのときは、フォーカスを合わせるまで表示されず、スライドアウトするはずのときは、マウスをその上に移動するまで消えていました。どちらの場合も、アニメーション化するのではなく、ポップイン/ポップアウトするだけです。

厄介なことに、プロジェクト中に、無関係な理由で4ではなく.net3.5に戻すことが決定されました。

したがって、問題は次のとおりです。(a)WebBrowserを適切にアニメーション化するにはどうすればよいですか。または(b)アニメーションの開始時にWebBrowserを非表示にし、終了時に再度表示するにはどうすればよいですか。アニメーションは現在XAMLで定義されており、特にコードに変更したくありません。

そして、フォローアップの質問は次のとおりです。まだ.net 3.5を使用しているより良い方法はありますか?

4

1 に答える 1

2

更新WPFWebBrowserは、WinForms WebBrowserに比べて非常に哀れなほど足りないので、WindowsFormsHostを使用して交換しました。以下のすべてが引き続き適用されますが、WebBrowserはそれほど混乱していません(たとえば、DocumentCompletedイベントがあります)。


WebBrowserをアニメーション化するオプションは非常に難しくなったため、すぐに諦め、代わりに非表示にして再表示することにしました。アニメーションの開始は、ビューモデルのコマンドによってトリガーされます。次に、表示する必要のあるページを見つけて作成し、遷移状態を反映する添付プロパティを介してアニメーションを開始します。

IRequireTransitionInfoを呼び出すと、IRequireTransitionInfo.TransitioningFromそれ自体を非表示にして再度表示する機会が与えられるように、インターフェイスを作成しましIRequireTransitionInfo.TransitioningToた。TransitioningFromは簡単でしたが、ストーリーボードが完成したときにTransitioningToを呼び出す必要がありました。

最初に、ビューモデルのコンストラクターで、ストーリーボードを探して、以下のコードのように、Completedイベントにフックしました。

    Storyboard animation = Application.Current.FindResource("SlideAnimation") as Storyboard;
    if (animation != null)
    {
      animation.Completed += new EventHandler(animation_Completed);
    }

そして、イベントハンドラー:

void animation_Completed(object sender, EventArgs e)
{
  IRequireTransitionInfo info = currentViewModel as IRequireTransitionInfo;
  if (info != null)
    info.TransitioningTo(currentView);
}

これは.net4でかなりうまく機能しているようです。.net3.5にダウングレードした後、Completedイベントをフックする上記のコードを実行すると、次のエラーが発生しました。

Specified value of type 'System.Windows.Media.Animation.Storyboard' must have IsFrozen set to false to modify.

SOに関する他の回答のいくつかにもかかわらず、凍結されたFreezableを解凍することはできず、コードをMainWindowのコンストラクターに移動しても役に立ちませんでした。

ビューモデルのコマンドにバインドされたストーリーボード上のアタッチされたプロパティのパスをたどりました。

<Storyboard x:Key="SlideAnimation" local:EventCommand.StoryboardCompleted="{Binding Source={StaticResource Locator}, Path=Current.MainViewModel.StoryboardCompletedCommand}">

ただし、これにより、実行時に次のエラーが発生しました。

Cannot convert the value in attribute 'ContentTemplate' to object of type 'System.Windows.DataTemplate'. Cannot freeze this Storyboard timeline tree for use across threads.

ストーリーボードではデータバインディングを実行できないようです(少なくとも.net 3.5では)。その結果、アタッチされたプロパティに、ストーリーボードの完了の通知をサポートするインターフェイスを実装することが期待されるリソースの文字列名を定義するだけで、問題をややエレガントに解決しました。

<Storyboard x:Key="SlideAnimation" local:EventCommand.StoryboardCompletedHandler="Locator">

.net 3.5でこの状況を処理するためのより良い方法を誰かが知っているなら、私は聞いてうれしいです。

于 2012-07-12T04:35:49.807 に答える