使用包装的语言资源 Xamarin Forms 更改语言运行时 [英] Change language runtime with wrapped language resources Xamarin Forms

查看:21
本文介绍了使用包装的语言资源 Xamarin Forms 更改语言运行时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在开发多个移动应用程序,它们之间带有通用 .NET Standard 库,其中包含通用功能.(MVVM)Common 项目有一个 TranslationManager 类和一个 Resource 文件,其中包含常见的翻译.TranslationManager 使用构造函数注入,注入应用程序特定的翻译资源.

We are developing several mobile apps, with Common .NET Standard library between them, which holds the common functionallity. (MVVM) The Common project has a TranslationManager Class, and a Resource file, which holds the common translations. TranslationManager uses constructor injection, to inject the app specific translation resources.

    public TranslationManager(ResourceManager appSpecificLanguageResources)
    {
        _commonResources = CommonTranslationResources.ResourceManager;
        _appSpecificLanguageResources = appSpecificLanguageResources;
    }

通过此代码,我们可以仅使用一个翻译提供程序就可以使用常见翻译和特定于应用程序的翻译.

With this code, we earn the possibilty to use common translations, and application specific translations with using only one Translation provider.

            if (string.IsNullOrWhiteSpace(translationKey))
                return null;
            string commonTranslation = _commonResources.GetString(translationKey, new CultureInfo(_preferenceCache.CultureName));
            string appSpecificTranslation = _appSpecificLanguageResources.GetString(translationKey, new CultureInfo(_preferenceCache.CultureName));
            if (commonTranslation == null && appSpecificTranslation == null)
            {
                MobileLogger.Instance.LogWarning($"Translate could not found by translationKey: {translationKey}");
                return $"TRANSLATION_{translationKey}";
            }
            if (!string.IsNullOrWhiteSpace(commonTranslation) && !string.IsNullOrWhiteSpace(appSpecificTranslation))
            {
                MobileLogger.Instance.LogDebug(TAG, $"Warning! Duplicate translate found for '{translationKey}' translationkey. Common translate is : '{commonTranslation}' , AppSpecific Translation is: {appSpecificTranslation}. Returning with appspecific translation.");
                return appSpecificTranslation;
            }
            if (commonTranslation == null)
                return appSpecificTranslation;
            else
                return commonTranslation;

在 XAML 中,我们有一个提供当前语言翻译的 MarkupExtension.

In XAML, we have one MarkupExtension which provides the translation for the current language.

public class TranslateMarkupExtension : IMarkupExtension
{
    public TranslateMarkupExtension()
    {

    }

    public string TranslationKey { get; set; }

    public object ProvideValue(IServiceProvider serviceProvider)
    {
        if (string.IsNullOrWhiteSpace(TranslationKey)) return "nullref";
        return Resolver.Resolve<TranslationManager>().GetTranslationByKeyForCurrentCulture(TranslationKey);
    }
}

XAML 用法似乎是这样的:

XAML Usage seem to be like:

  Entry Placeholder="{extensions:TranslateMarkup TranslationKey=PlaceholderPhoneNumber}"

问题是,当我在运行时设置语言时,翻译扩展标记不会评估新的翻译.

The problem is, when i set the language at runtime, the translation extension markup does not evaluate the new translation.

使用 null 参数提升 propertychanged 会刷新视图上的绑定,但不会影响 MarkupExtensions.

Raising propertychanged with null parameter refreshes the bindings on the view, but does not affect MarkupExtensions.

我不想将同一个页面推送到导航堆栈,这对我来说似乎是拼凑的.

I do not want to push the same page to the navigation stack, it seems patchwork for me.

推荐答案

public class TranslateExtension : IMarkupExtension<BindingBase>
{       
    public TranslateExtension(string text)
    {
        Text = text;            
    }

    public string Text { get; set; }

    object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
    {
        return ProvideValue(serviceProvider);
    }

    public BindingBase ProvideValue(IServiceProvider serviceProvider)
    {
        var binding = new Binding
        {
            Mode = BindingMode.OneWay,
            Path = $"[{Text}]",
                Source = Translator.Instance,
        };
    return binding;
    }        
}

这是最初提议的 Translator 类,但为了清楚起见,这里复制了 GetString 调用:

and this the Translator class as initially proposed, but reproduced here for clarity with the GetString call:

public class Translator : INotifyPropertyChanged
{
    public string this[string text]
    {
    get
    {
        return Strings.ResourceManager.GetString(text, Strings.Culture);
    }
    }        

    public static Translator Instance { get; } = new Translator();

    public event PropertyChangedEventHandler PropertyChanged;

    public void Invalidate()
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
    }
}

绑定文本:

{i18n:Translate Label_Text}

要触发语言更新,您只需调用:

To trigger the update of languages you just then need to call:

Translator.Instance.Invalidate()

解决方案来自:https://forums.xamarin.com/discussion/82458/binding-indexername-and-binding-providevalue-in-xamarin-forms

这篇关于使用包装的语言资源 Xamarin Forms 更改语言运行时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆