mvvmcross导航问题,得到异常:无法找到[ViewModelName]的视图
本文关键字:ViewModelName 视图 问题 导航 mvvmcross 异常 | 更新日期: 2023-09-27 17:50:47
我似乎很困惑,如何使MvvmCross检测我的ViewModels是与视图在Mono Android。我试着按照TwitterSearch来实现导航,但它就是不起作用。
RequestNavigate<LoginViewModel>();
这是我的观点:
[Activity(Label = "Login")]
public class LoginActivity : MvxBindingActivityView<LoginViewModel>
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
App.InitializeRestConnection(this);
}
protected override void OnViewModelSet()
{
SetContentView(Resource.Layout.LoginBindable);
}
}
这里有一个例外:
I/ActivityManager( 307): Displayed com.desco.pendulum/pendulum.androidapp.SplashScreenActivity: +1s373ms (total +4s420ms)
I/Navigation( 8643): 0.50 Navigate to LoginViewModel with args
I/mono-stdout( 8643): Navigation:Diagnostic: 0.50 Navigate to LoginViewModel with args
I/MonoDroid( 8643): UNHANDLED EXCEPTION: System.Collections.Generic.KeyNotFoundException: Could not find view for dESCO.Mobile.ViewModels.LoginViewModel
I/MonoDroid( 8643): at Cirrious.MvvmCross.Views.MvxViewsContainer.GetViewType (System.Type) <0x001a4>
I/MonoDroid( 8643): at Cirrious.MvvmCross.Droid.Views.MvxAndroidViewsContainer.GetIntentFor (Cirrious.MvvmCross.Views.MvxShowViewModelRequest) <0x00023>
I/MonoDroid( 8643): at Cirrious.MvvmCross.Droid.Views.MvxAndroidViewPresenter.Show (Cirrious.MvvmCross.Views.MvxShowViewModelRequest) <0x00037>
I/MonoDroid( 8643): at Cirrious.MvvmCross.Droid.Views.MvxAndroidViewDispatcher/<>c__DisplayClass1.<RequestNavigate>b__0 () <0x0002f>
I/MonoDroid( 8643): at Java.Lang.Thread/RunnableImplementor.Run () <0x0003f>
I/MonoDroid( 8643): at Java.Lang.IRunnableInvoker.n_Run (intptr,intptr) <0x00037>
I/MonoDroid( 8643): at (wrapper dynamic-method) object.7060b187-418d-4bca-ad4f-8b9cae936501 (intptr,intptr) <0x0003b>
有什么建议吗?
我看不出你的设置有什么明显的问题。
默认的Droid框架设置查找在ExecutingAssembly中使用以下逻辑实现IMvxAndroidView的类:https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross/Platform/MvxBaseSetup.cs#L200
所以我看不出任何明显的原因为什么你的LoginActivity视图没有被捡起来。
你可以做的一件事是在Setup.cs中添加一些调试代码,以查看正在检测的视图:
protected override IDictionary<Type, Type> GetViewModelViewLookup()
{
var toReturn = base.GetViewModelViewLookup();
MvxTrace.Trace("Tracing viewModels and views");
foreach (var kvp in toReturn)
{
MvxTrace.Trace("Seen pair {0} : {1}", kvp.Key.Name, kvp.Value.Name);
}
return toReturn;
}
如果这显示列表是空的或缺少你的活动,那么恐怕我们需要通过反射逻辑来找出为什么它不拾取你的活动。
在真正绝望的时候,你也可以伪造结果:
protected override IDictionary<Type, Type> GetViewModelViewLookup()
{
return new Dictionary<Type,Type>() { { typeof(LoginViewModel), typeof(LoginActivity) } };
}
但这可能不是你的长期解决方案
如果这是由某种"解决方案设置"的差异引起的——例如,如果你把你的setup .cs放在不同的项目中,那么可能以某种方式重写默认约定会帮助你。
要实现这一点,在Setup.cs中,重写代码: public virtual Assembly ExecutableAssembly
{
get { return GetType().Assembly; }
}
protected override IDictionary<System.Type, System.Type> GetViewModelViewLookup()
{
return GetViewModelViewLookup(ExecutableAssembly, typeof (IMvxAndroidView));
}
中的基本设置类- https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Droid/Platform/MvxBaseAndroidSetup.cs
这可以通过重写ExecutingAssembly属性(尽管给定它的名称似乎有点错误)或重写GetViewModelViewLookup方法来完成。例如,如果您想查看几个单独的程序集,您可以使用:
public List<Assembly> MyViewAssemblies { get; set; }
protected override IDictionary<System.Type, System.Type> GetViewModelViewLookup()
{
var toReturn = new Dictionary<Type, Type>();
foreach (var assembly in MyViewAssemblies)
{
var contributions = base.GetViewModelViewLookup(assembly, typeof (IMvxAndroidView));
foreach (var kvp in contributions)
{
toReturn[kvp.Key] = kvp.Value;
}
}
return toReturn;
}