Ссылка, которую разместил @AdamVincent, и «отсутствующие» методы очень полезны для обычной навигации вида / представления по модели, используя ViewModelLocationProvider.Однако при попытке использовать две модели представления для одного и того же представления они не работают.Это связано с тем, что внутри метода расширения есть вызов, который регистрирует модель представления в представлении для использования ViewModelLocationProvider.
private static IUnityContainer RegisterTypeForNavigationWithViewModel<TViewModel>(this IUnityContainer container, Type viewType, string name)
{
if (string.IsNullOrWhiteSpace(name))
name = viewType.Name;
ViewModelLocationProvider.Register(viewType.ToString(), typeof(TViewModel));
return container.RegisterTypeForNavigation(viewType, name);
}
Внутренне ViewModelLocationProvider.Register использует словарь для хранения связи между моделями представления и представлениями.,Это означает, что если вы зарегистрируете две модели представления в одном представлении, вторая будет перезаписывать первую.
Container.RegisterTypeForNavigation<PageA, ViewModelA>("PageA1");
Container.RegisterTypeForNavigation<PageA, ViewModelB>("PageA2");
Таким образом, при использовании вышеуказанных методов при использовании ViewModelLocationProvider он всегда будет создавать экземпляр ViewModelB, поскольку он был последним зарегистрированным.
Кроме того, следующая строка вызываетRegisterTypeForNavigation, который сам в конечном счете вызывает Container.RegisterType, только передает viewType.
Чтобы решить эту проблему, я решил его другим способом, используя свойство Injection.У меня есть следующий метод для привязки моей модели представления к моему представлению
private void BindViewModelToView<TView,TViewModel>(string name)
{
if (!Container.IsRegistered<TViewModel>())
{
Container.RegisterType<TViewModel>();
}
Container.RegisterType<TView, TViewModel>(name,new InjectionProperty("DataContext", new ResolvedParameter<TViewModel>()));
}
Мы знаем, что каждое представление будет иметь свойство DataContext, поэтому свойство Injection будет вставлять модель представления непосредственно в DataContect для представления.
При регистрации моделей представления вместо использования RegisterTypeForNavigation вы должны использовать следующие вызовы:
BindViewModelToView<PageA,ViewModelA>("ViewModelA");
BindViewModelToView<PageA,ViewModelB>("ViewModelB");
Для создания представления у меня уже есть метод, который я использую для добавления соответствующего представления в мой регион.и он работает, используя имя представления в качестве ключа для получения правильного экземпляра модели представления.
private object LoadViewIntoRegion<TViewType>(IRegion region, string name)
{
object view = region.GetView(name);
if (view == null)
{
view = _container.Resolve<TViewType>(name);
if (view is null)
{
view = _container.Resolve<TViewType>();
}
region.Add(view, name);
}
return view;
}
Который я просто вызываю с помощью
var view = LoadViewintoRegion<PageA>(region,"ViewModelA");
и
var view = LoadViewintoRegion<PageA>(region,"ViewModelB");
Поэтому для обычных моделей View / Viewmolels я использую свойство ViewModelLocationProvider.AutoWireViewModel, а там, где у меня несколько моделей представления, я использую этот альтернативный подход.