WinRT や を使用したことがないので、私の理解は少し緊張しているかもしれませんが、RT の一部であり、ビューモデルの解像度とフレームのナビゲーションを提供してINavigationService
いると思います。Frame
INavigationService
私のもう 1 つの仮定は、あなたのフレームはすでにコンダクターに少し似ているということです。フレームで 'Navigate()' を呼び出すと、フレームのコンテンツが新しく指定されたコンテンツに置き換えられるだけです。この場合、CM はビューモデルのビューの最初の解決を行っています。
コンダクターのルートに行きたいので、CM の実装を捨ててINavigationService
、独自のナビゲーション メソッドを処理するようにします (たとえば、 sメソッドをINavigationService
スキップします)。Frame
Navigate()
CM ソースをざっと見てみると、すべてがフレームでイベントをNavigationService
処理しNavigate
、次に VM の解決とビューの設定を行っていることがわかります (コンダクターはおそらく既に行っていることです)。あなたがする必要があるINavigationService
のは、フレームをナビゲートする代わりに、実装が指定されたビューをシェルにロードするだけであることを確認することです
のコンストラクター コードを盗んでNavigationService
の実装を変更し、x が VM のインスタンスであるシェルをNavigate()
呼び出すだけで済みます。ActivateItem(x)
CM が残りの処理を行います (CM ブーストラップはルートの「フレーム」も既にセットアップしていると思いますので、心配する必要はありません)。
例えば
実装は次のようになります (これは私がまとめたものであり、むき出しの嘘である可能性があることに注意してください!):
public class NewFrameAdapter : INavigationService
{
private readonly Frame frame;
private readonly IConductActiveItem shell;
private event NavigatingCancelEventHandler ExternalNavigatingHandler = delegate { };
public NewFrameAdapter(Frame frame)
{
this.frame = frame;
// Might want to tighten this up as it makes assumptions :)
this.shell = (frame as FrameworkElement).DataContext as IConductActiveItem;
}
public bool Navigate(Type pageType)
{
// Do guardclose and deactivate stuff here by looking at shell.ActiveItem
// e.g.
var guard = shell.ActiveItem as IGuardClose;
if (guard != null)
{
var shouldCancel = false;
guard.CanClose(result => { shouldCancel = !result; });
if (shouldCancel)
{
e.Cancel = true;
return;
}
}
// etc
// Obviously since the guard is probably async (assume it is, if not you are ok to continue!) you'd have to not call this code right
// here but I've just stuck it in here as an example
// edit: looking at the code above (the guard code) it looks like this is all sync so the below code should be fine
// You might get away with calling shell.ActivateItem(pageType) as I'm not sure
// if the viewmodel binder in RT would resolve this all for you, but if it doesnt...
// Init the view and then resolve the VM type
ViewLocator.InitializeComponent(pageType);
var viewModel = ViewModelLocator.LocateForView(pageType);
// Activate the VM in the shell)
shell.ActivateItem(viewModel);
}
これを独自の方法で転がすのはそれほど難しくありません。これはまったく役に立ちますか?
次に、XAML は非常に単純になります。
<Frame blah blah>
<SomeStaticContent />
<ContentControl x:Name="ActiveItem" /> <!-- The dynamic bit... -->
<SomeMoreStaticContent />
</Frame>
これはおそらくビュー ファーストとビューモデル ファーストのハイブリッドになると考えています。これは、ルートFrame
がビュー ファーストを使用し、コンダクターが使用しActivateItem()
てビューモデルを取得し、バインダーが起動したときにビューを解決するためです。しかし、私の仮定が正しければ、うまくいくはずです