更新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でこの状況を処理するためのより良い方法を誰かが知っているなら、私は聞いてうれしいです。