简体   繁体   中英

Resource file wrapper not created for Portable class in Visual Studio 2015

I'm trying to include a resource file in a portable class and according to this article by Microsoft ( App Resources for Libraries That Target Multiple Platforms ), I should set the Access Modifier to public:

To create a strongly typed wrapper in Visual Studio, set the main resource file's Access Modifier in the Visual Studio Resource Designer to Public. This creates a [resourceFileName].designer.cs or [resourceFileName].designer.vb file that contains the strongly typed ResourceManager wrapper.

And then I should be able to access the resource directly by using the wrapper class that was supposed to be created. My resource files are named SharedResources.en-US.resx; SharedResources.fr-FR.resx, etc...

So I should be able to access this calling the following wrapper class:

string str = SharedResources.UnsupportedFeature;

But it doesn't create any wrapper file for the resource file, even after I go from Internal to Public . I thought maybe it was because I had stored them in a Strings folder so I moved my various resource files to the root of my project but it made no difference.

Anyone has any ideas or suggestions as to how I can resolve this?

Thanks.

UPDATE 1:

Strange, I noticed that when I create a new resource file just called Resources.resx, it will create the following in Resources.Designer.cs:

namespace MyCompany.MyApp.Shared.Strings {
    using System;
    using System.Reflection;

    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute
    ("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    internal class Resources {  
        private static global::System.Resources.ResourceManager resourceMan;    
    private static global::System.Globalization.CultureInfo
        .resourceCulture;

        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute
        ("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
    internal Resources() {
}

/// <summary>
///   Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute
    (global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager 
    {
    get {
      if (object.ReferenceEquals(resourceMan, null)) {
             global::System.Resources.ResourceManager temp = new
             global::System.Resources.ResourceManager
             ("MyCompany.MyApp.Shared.Strings.Resources", 
             typeof(Resources).GetTypeInfo().Assembly);
    resourceMan = temp;
      }
      return resourceMan;
        }
    }

    /// <summary>
    ///   Overrides the current thread's CurrentUICulture property for all
    ///   resource lookups using this strongly typed resource class.
    /// </summary>
    [global::System.ComponentModel.EditorBrowsableAttribute
    (global::System.ComponentModel.EditorBrowsableState.Advanced)]
    internal static global::System.Globalization.CultureInfo Culture {
    get {
        return resourceCulture;
    }
    set {
        resourceCulture = value;
    }
    }

    /// <summary>
    ///   Looks up a localized string similar to Unsupported 
    ///   feature provided.
    /// </summary>
    internal static string UnsupportedFeature {
        get {
        return ResourceManager.GetString("UnsupportedFeature",
                   resourceCulture);
            }
        }
    }
}
  • If I rename the file, this code is completely removed.
  • If I create a file called Resources.fr-FR.resx, the code is not created.

I'll play around with the above code and see if I get anywhere.

Ok, I figured it out. It's either not very well explained in the Microsoft article I've mentioned or I've totally missed that part. Either way, here's how you get it to work:

From your portable library:

  1. Create a default called Resources.resx (or whatever you want but keep the name simple ie no dot, dash, etc...) or it will not generate the default code in the Resources.Designer.cs

  2. Make sure to make the Access Modifier public as mentioned in the article.

  3. Add your resource strings as you normally would via the resource editor.

  4. Create a new resource file for the relevant language you need and name it based on the default one but add the relevant language code to it ie Resources.fr-FR.resx. Note that this one will not contain any code in the Resources.Designer.fr-FR.cs (and that's ok!)

  5. Add your resource strings as you normally would via the resource editor to match the entries of the default.

  6. Create a helper class similar to this in your portable class library:

    internal class LocalizeHelper { public enum LocalizeStringsEnum { UnsupportedFeature }

     public static string GetText(LocalizeStringsEnum key) { switch (key) { case LocalizeStringsEnum.UnsupportedFeature: return Resources.UnsupportedFeature; default: // Should never be raised unless a key is not defined in the enum. throw new ArgumentOutOfRangeException("Unknown key provided"); } } 
  7. To call it from your Portable Class Library, you would then call it this way:

    public bool MyFunction() { throw new Exception(LocalizeHelper.GetText (LocalizeStringsEnum.UnsupportedFeature)); }

That's it!

From your App:

Assuming your app is a UWP app, make sure to set the PrimaryLanguageOverride in the OnLaunched method:

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    ApplicationLanguages.PrimaryLanguageOverride = "fr-FR"; //To test
    //ApplicationLanguages.PrimaryLanguageOverride =  //Run-time
    //GlobalizationPreferences.Languages[0];
}

then in your code, it would be something similar to this:

try
{
    bool test = MyPortableLib.MyFunction();
}
catch (Exception ex)
{
    Debug.WriteLine(ex.Message);
}

And the above will display an exception in french (or whatever your primary language has been set to).

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM