Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 89864

XF Localization in XAML Where Strings Come from Separate .net 2.0 PCL

$
0
0

Hi

I have followed the localisation guide here: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/localization/text?tabs=windows

If I include my AppResources.resx within my forms project, XAML picks up the translations just fine, but this is NOT how I wish to proceed.

I wish to have the translations in a separate project, currently a .net2.0 library MyApp.Shared.Resources this project contains only the AppResources.resx file in the project root together with the associated AppResources.Designer.cs

I have changed the CustomTool field to PublicResXFileCodeGenerator as per the documentation.

The error I see is:

System.Exception: 'Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "ProteusPatientApp.Shared.Resources.AppResources.resources" was correctly embedded or linked into assembly "ProteusPatientApp" at compile time, or that all the satellite assemblies required are loadable and fully signed.'


In my forms project, I have the required extension thus:

using MyApp.Shared.Interfaces;
using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace MyApp.Helpers
{
    // You exclude the 'Extension' suffix when using in XAML
    [ContentProperty("Text")]
    public class TranslateExtension : IMarkupExtension
    {
        // You exclude the 'Extension' suffix when using in XAML
        readonly CultureInfo ci = null;
        const string ResourceId = "MyApp.Shared.Resources.AppResources";

        static readonly Lazy<ResourceManager> ResMgr = new Lazy<ResourceManager>(() => new ResourceManager(ResourceId, IntrospectionExtensions.GetTypeInfo(typeof(TranslateExtension)).Assembly));

        public string Text { get; set; }

        public TranslateExtension()
        {
            if (Device.RuntimePlatform == Device.iOS || Device.RuntimePlatform == Device.Android)
            {
                ci = DependencyService.Get<ILocalize>().GetCurrentCultureInfo();
            }
        }

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (Text == null)
                return string.Empty;

            var translation = ResMgr.Value.GetString(Text, ci);
            if (translation == null)
            {
#if DEBUG
            throw new ArgumentException(
                string.Format("Key '{0}' was not found in resources '{1}' for culture '{2}'.", Text, ResourceId, ci.Name),
                "Text");
#else
                translation = Text; // HACK: returns the key, which GETS DISPLAYED TO THE USER
#endif
            }
            return translation;
        }
    }
}

In my XAML, I have:

xmlns:helpers="clr-namespace:ProteusPatientApp.Helpers;assembly=ProteusPatientApp"
<Label Text="{helpers:Translate CompletedPatientEvents}" Margin="0,5,0,10" FontSize="25"  TextColor="{StaticResource SL_DarkBlue}" FontAttributes="Bold" HorizontalOptions="Center" VerticalOptions="Start"/>

I don't believe I am doing anything wrong - eg I am following the guide. My only route if I cannot share resources between projects is to roll my own resources manager, or duplicate the resources across every project that requires them. Both are a bit of a wind up!

If I plonk this code:

var assembly = typeof(Shared.Resources.AppResources).GetTypeInfo().Assembly; // "EmbeddedImages" should be a class in your app
foreach (var res in assembly.GetManifestResourceNames())
{
System.Diagnostics.Debug.WriteLine("found resource: " + res);
}

Into App.xaml.cs constructor, I see output:

Found resource: "ProteusPatientApp.Shared.Resources.AppResources.resources"

EG, the XAML code can see the project that contains my resources just fine.

Anyone got any idea's how to resolve?


Viewing all articles
Browse latest Browse all 89864

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>