WPFでViewを今のウィンドウとは別のウィンドウに表示させたい時


WPFでデスクトップアプリケーションを作っていてこのViewを別のウィンドウにも表示したいなと思うことがあります。

大抵の場合はMVVMですとViewModelをもとにViewをDataTemplateとかで紐付ければOKなのですが、そんなに簡単にやらせてくれるコントロールばかりではないですよね。

例えばWebBrowserコントロールとか。

現在WebBrowserコントロールで表示しているものを別のウィンドウで表示したいとなった時に非常に悩みます。

1483339947316

例えばこのNicoNicoViewerのWebBrowserコントロールの部分をフルスクリーンのウィンドウに移動したいときなど。(※画面は開発中のものです!)

DataTemplateだとフルスクリーンにした時にWebBrowserの初期化処理が走って一からロードし直しになってしまうので困ってしまいます。

何かいい方法な無いか考えて私が試行錯誤した結果

※ここではMVVMインフラにLivetを使用しています

ViewModel側にWebBrowserのインスタンスをもたせ

こんな感じでContentに直接WebBrowserコントロールをバインドすればうまいこと表示されます。

次にフルスクリーン側のViewでも上と同じXAMLを書いてフルスクリーンのViewを表示すれば

1483340995083

もとのウィンドウからはWebBrowser部分が消えてフルスクリーン側に行ってくれました。

もとに戻す時は

と一度WebBrowserプロパティにnullを代入してから再度同じインスタンスを代入するともとの位置に戻ってくれます。

この辺もうちょっとなんとかならないかな・・・

 

WebBrowserコントロールではなく普通のUserControlでも同じように書けば動きます。

どうしてもViewを同じインスタンスでないと困るという時は役に立つかもしれません。

 

ただ

 

そのViewにPopupコントロールが含まれていると話が変わってきます。

Popupが含まれているとフルスクリーンにして戻ってきた時にIsOpenがtrueになっても表示されなくなってしまいます。

原因はさっぱり分からないという・・・

私の場合、WebBrowserコントロールと一緒にVideoControllerというViewも一緒に移動させているのですが、フルスクリーンから戻ってきた時にVideoControllerにあるPopupが一切反応しなくなってしまいました。

解決策としては

このようにフルスクリーンとそうでない時のプロパティを分けて別々にバインドさせればPopupも正しく動きました。

訳わかめですね。

WPFでこんなことするやつおらんやろwって感じはありますがggっても全然見つからなかったので記事にしてみました。

他にいい方法があるよ!という方はぜひ教えてください。

 

 

カテゴリー: C#, WPF パーマリンク

コメントを残す