C# MvvmCross-使用活动(上下文)参数实例化ViewModel

C# MvvmCross-使用活动(上下文)参数实例化ViewModel,c#,android,xamarin,mvvm,mvvmcross,C#,Android,Xamarin,Mvvm,Mvvmcross,使用MvvmCross,我创建了一个跨平台的方法来翻译Android和iOS上的字符串,这样我就可以在我的ViewModel中使用一个共享的translate()方法。在我的核心项目中,我有一个共享接口ILocalizationHelper,在每个平台中,我创建了一个从接口继承的LocalizationHelper类。因此,我的ViewModel现在包含一个ILocalizationHelper实例,我可以在该实例上使用我的translate()方法 问题:要使用GetString()在Andr

使用MvvmCross,我创建了一个跨平台的方法来翻译Android和iOS上的字符串,这样我就可以在我的
ViewModel
中使用一个共享的
translate()
方法。在我的核心项目中,我有一个共享接口
ILocalizationHelper
,在每个平台中,我创建了一个从接口继承的
LocalizationHelper
类。因此,我的
ViewModel
现在包含一个
ILocalizationHelper
实例,我可以在该实例上使用我的
translate()
方法

问题:要使用
GetString()
在Android上翻译字符串,我需要一个上下文(活动)。因此,实例化这个
LocalizationHelper
并不简单。目前,我在我的
MvxViewModel
中使用一个
Translator
属性来解决这个问题,我可以从视图中设置该属性

我的
Fragment
类如下:

[MvxFragment(typeof(AccountViewModel), Resource.Id.content_frame, AddToBackStack = true)]
[Register("appname.Android.Fragments.Account.LoginFragment")]
public class LoginFragment : MvxFragment<LoginViewModel>
{
    base.OnCreateView(inflater, container, savedInstanceState);
    View view = this.BindingInflate(Resource.Layout.FragmentLogin, container, false);

    ViewModel.Translator = new LocalizationHelper(Activity);
}

感谢您对这方面的最佳实践的启发。

您可以利用
IMvxAndroidCurrentTopActivity
,它是针对当前top
活动注册的,以获取android
本地化助手
实现中的活动上下文


var context=Mvx.Resolve().Activity

您可以在DependencyContainer中注册
ApplicationContext
,并将其注入
LocalizationHelper
实现中


如果必须使用当前活动上下文,则可以将其注册为
Func
(并在每次调用
Translate
)时解析它)或者按照@Plac3Hold3r的建议,将IMvxAndroidCurrentTopActivity注入
LocalizationHelper
实现。

初始化
LocalizationHelper
时,应设置
上下文。我假设这可以看作是一个单例,所以最好的方法是在Android项目中的
设置
类中

重写
初始化firstchance()
并向Mvx IoC注册单例。然后,您将能够在ViewModel中使用构造函数注入

由于上下文已经被singleton捕获,因此您的ViewModel不必担心它。这就是插件的工作原理(尽管Mvx有插件的自动注册)

公共类设置:MvxAndroidSetup
{
专用只读上下文\u应用程序上下文;
公共设置(上下文应用上下文):基本(应用上下文)
{
//保存应用程序上下文的副本
_applicationContext=applicationContext;
}
受保护的重写void InitializeFirstChance()
{
base.InitializeFirstChance();
//实例化并注册帮助程序
RegisterSingleton(新本地化助手(_applicationContext));
}
}
公共类MyViewModel:MvxViewModel
{
私有只读ILocalizationHelper\u localizationHelper;
//辅助单例构造器
公共MyViewModel(ILocalizationHelper本地化Helper)
{
_localizationHelper=localizationHelper;
//现在,您可以从ViewModel的其余部分使用_localizationHelper
}
}

谢谢,我发现了IMvxAndroidCurrentTopActivity,但不知道在哪里可以使用它。VS以前也不允许我导入它,因为我在错误的方法/类中使用了它。您的解决方案也解决了我的问题,但因为我认为我的类是全局的,所以我更喜欢使用应用程序上下文方法。谢谢!:)谢谢你的详细解释。我现在理解了它的工作原理:)通过“在DependencyContainer中注册”,你可能是指Mvx.register…()对吧,就像@Kiliman的答案一样?还是有别的办法?谢谢你的帮助!
private ILocalizationHelper _translator;

public ILocalizationHelper Translator
{
    get { return _translator; }
    set { _translator = value; }
}    

public LoginViewModel(ILocalizationHelper localizationHelper)
{
    _translator = localizationHelper;
}
public class Setup : MvxAndroidSetup
{
    private readonly Context _applicationContext;

    public Setup(Context applicationContext) : base(applicationContext)
    {
        // save copy of application context
        _applicationContext = applicationContext;
    }

    protected override void InitializeFirstChance()
    {
        base.InitializeFirstChance();

        // instantiate and register helper
        Mvx.RegisterSingleton<ILocalizationHelper>(new LocalizationHelper(_applicationContext));
    }
}


public class MyViewModel : MvxViewModel
{
    private readonly ILocalizationHelper _localizationHelper;

    // constructor injector of helper singleton
    public MyViewModel(ILocalizationHelper localizationHelper)
    {
        _localizationHelper = localizationHelper;

        // you will now be able to use _localizationHelper from the rest of the ViewModel
    }

}