После некоторых испытаний ниже предлагается предлагаемое решение. Я не на 100% влюблен в него, но он действительно работает и предоставляет опыт разработчиков типов, которые я искал. Итак, давайте заглянем.
Для начала все мои модели ViewModels (VM) наследуют от базы VM, AVM.Этот абстрактный базовый класс поддерживает поиск объекта как общедоступного статического метода. Это немного грубо, но это хорошо работает, если вы хотите потягивать Kool-Aid. Ниже приводится часть класса, это отношение к этой проблеме:
public abstract class AVM : MvxViewModel {
private static readonly Dictionary<Guid, WeakReference> ViewModelCache = new Dictionary<Guid, WeakReference>();
private static readonly string BUNDLE_PARAM_ID = @"AVM_ID";
private Guid AVM_ID = Guid.NewGuid();
private Type MyType;
protected AVM()
{
MyType = this.GetType();
ViewModelCache.Add(AVM_ID, new WeakReference(this));
}
public static bool TryLoadFromBundle(IMvxBundle bundle, out IMvxViewModel viewModel)
{
if (null != bundle && bundle.Data.ContainsKey(BUNDLE_PARAM_ID))
{
var id = Guid.Parse(bundle.Data[BUNDLE_PARAM_ID]);
viewModel = TryLoadFromCache(id);
return true;
}
viewModel = null;
return false;
}
private static IMvxViewModel TryLoadFromCache(Guid Id)
{
if (ViewModelCache.ContainsKey(Id))
{
try
{
var reference = ViewModelCache[Id];
if (reference.IsAlive)
return (IMvxViewModel)reference.Target;
}
catch (Exception exp) { Mvx.Trace(exp.Message); }
}
return null;
}
protected void View()
{
var param = new Dictionary<string, string>();
param.Add(BUNDLE_PARAM_ID, AVM_ID.ToString());
ShowViewModel(MyType, param);
}
Для того, чтобы получить все это проводной, вы должны создать пользовательский вид модели локатора. Вот пользовательский локатор:
public class AVMLocator : MvxDefaultViewModelLocator
{
public override bool TryLoad(Type viewModelType, IMvxBundle parameterValues, IMvxBundle savedState, out IMvxViewModel viewModel)
{
if (AVM.TryLoadFromBundle(parameterValues, out viewModel))
return true;
return base.TryLoad(viewModelType, parameterValues, savedState, out viewModel);
}
}
Наконец, вам нужно подключиться. Для этого перейдите в ваш App.cs и переопределить CreateDefaultViewModelLocator следующим образом:
protected override IMvxViewModelLocator CreateDefaultViewModelLocator()
{
return new AVMLocator();
}
Ты весь набор. Теперь в любом из полученных ViewModels, которые уже живы и здоровы, вы можете сделать следующее:
myDerivedVM.View();
Там еще некоторые более мне нужно сделать (например, убедившись, что WeakReferences делать свою работу, и у меня нет утечки памяти и некоторая дополнительная обработка ошибок), но, по крайней мере, это тот опыт, который я собирался сделать. Последнее, что я сделал, добавьте следующую команду в базовый класс АВМ:
public MvxCommand ViewCommand
{
get { return new MvxCommand(View); }
}
Теперь вы можете связать эту команду к любому объекту пользовательского интерфейса и при вызове, он будет запускать эту точку зрения с той самой экземпляр виртуальной машины ,
Стюарт, спасибо за помощь в управлении мной в правильном направлении. Мне было бы интересно услышать ваши отзывы о решении, которое я вам предоставил. Спасибо за всю вашу работу с MVVMCross. Это действительно красивый код.
Cheers.
Стюарт, большое вам спасибо за помощь. Я действительно шел по описанной вами дороге, и я думаю, что придумал решение, которое работает достаточно хорошо. Я изменил свой вопрос, чтобы показать предлагаемое решение. Хотелось бы услышать ваши мысли об этом. Еще раз спасибо за вашу помощь. – Joe