I'm having a little trouble getting localized resources files to work on Windows Phone 7. Here's what I'm doing:
Create a resource file, say "Strings.resx" (Build Action: Compile)
Create a key, say "TestKey" with a default value of empty string
Add a English resource file in the same folder with a value of "some English string": Strings.en-us.resx (Build Action: Embedded Resource)
Add a Japanese resource file in the same folder with a value of "some Japanese string": Strings.ja-jp.resx (Build Action: Embedded Resource)
In my PC Silverlight, WPF Apps that works fine when I change the Thread.CurrentThread.CurrentCulture. But in the phone I always seem to be getting the value that's in the Strings.resx file - an empty string.
I have tried using the designer generated code and wiring up the resource manager by hand and it does not seem to matter. Here's my code:
Type t = typeof(Strings);
_resourceManager = new ResourceManager(
t.Namespace + "." + t.Name,
t.Assembly);
_resourceManager.GetString("TestKey");
Tell me localized resources are supported on the phone... ;> What am I doing wrong? Thanks!
Update: Thanks Olivier for forwarding the link. I saw that as well but missed an important step. I didn't add the "SupportedCultures" node to my csproj. Made all the difference - hoping someone else doesn't loose two hours trying to figure this out like I did.
<SupportedCultures>de-DE;es-ES;</SupportedCultures>
Of course, localized resources are supported on the phone:
How to: Build a Localized Application for Windows Phone
I wrote a blog post that provides links to a bunch of Globalization / Localization guides for WP7. There is a Windows Phone 7 in 7 Training video that helped me understand the basics. After that it was simply a matter of learning how to do databinding:
The MSDN article shows you how to
setup the files and create the
LocalizedStrings class, but they then
assume that you know how to use that
class for data binding. Visual Studio
2010 and Silverlight handle data
binding differently than Winforms, and
it gets even more confusing since XAML
also has it’s own definition of
Resources that are different then the
.NET resources we just created.
Silverlight also uses the term
Resource to refer to files that use
the the Build Action of "Content”, as
these files get wrapped up into the
.XAP file similar to how files with
Build Action of "Resource” get
embedded into the .Dll assembly (ex:
loading an image from content or
resource files). I found that instead
of using the Text="{Binding
Path=resourceFile.resourceName,
Source={StaticResource
Localizedresources }}" XAML syntax it
was easier to use the following steps:
Open your primary XAML page (usually MainPage.xaml) in the Visual
Studio designer
Open the properties for the PhoneApplicationPage and set the
DataContext to be
Application.Resources –>
LocalizedStrings. NOTE: if you already
are using a DataContext object, then
you should integrate the
LocalizedStrings class into that
object so that it has localization
support.
Once the Page’s DataContext has been set you can change the data
binding for any control on the page by
simply selecting the property (ex:
text, checked, etc), selecting “Apply
Data Binding…”, and setting the Path
to Localizedresources.BtnText or
whatever the name of the desired
resource value is.
Related
This msdn link says that to add more language to your windows phone app, you need to make changes in the supported culture box in the properties page, but I can't find such box in the properties page as well as manifest page.
I tried searching all the tabs and I have uploaded the screenshots of properties page as well as manifest, but I'm not able to find the required box.
I have developed an application and updated on the store but only English (US) is the supported language and I'm not able to localize the app.
I'm not able to add screenshots as it requires more that 10 reputation.
Adding resource files
You do not specify what languages you support in the project properties any more. You only specify the default language in the app manifest.
You have to manually add one .resw file for each language you support. The files must all be named Resources.resw and must be placed in a sub-folder, named after the language, under a “Strings” folder in your project.
Accessing resources from xaml
You access the resources by setting the x:Uid property of a control to a unique name. Unfortunately the x:Uid property is not recognized by the properties window, neither in VisualStudio nor in Blend, so you must hand code it directly in the xaml file.
Example:
<TextBlock x:Uid="MyTextBlock" /> <Button x:Uid="MyButton" />
<TextBlock x:Uid="MyTextBlock" />
You must then add a resource with the uid-name with dot-notation, that is, after the dot you write the name of the property of the control in which you want the text.
Reference : http://www.jayway.com/2014/04/22/windows-phone-8-1-for-developers-localizing-apps/
Summary of Solutons: The core issue was that I had my resx files in subfolders within App_LocalResources and App_GlobalResources. Separating things into folders is fine on .NET but Mono only looks at the files in those folders ignoring any sub folders.
Issue #2 works only at runtime. In other words the Resources namespace can be used in the aspx or in code in a script block in the page but not in the code behind. It seems that I've never used the Resources namespace in the code-behind proper so all 3 of my issues are solved.
I have an ASP.NET application I was previously working on on .NET on a PC and am trying to move over to a Mac to develop using Mono and MonoDevelop. The application utilizes the App_GlobalResources and App_LocalResources folders. The application worked on .NET but does not function properly on Mono as I will outline. The version information is below:
OS: Mac OS 10.8.2
Mono: 2.10.9
ASP.NET: 4.0.30319.1
MonoDevelop: 3.0.5
I've tagged this with MonoDevelop because I'm not sure what server is being used and whether it is a part of MonoDevelop or Mono itself or is separate. I'm not familiar enough yet with Mono and it's parts...
The issues I'm having revolve around accessing resources and I'm having various related issues which I'll outline below:
Issue 1: meta:resourcekey doesn't work and "a resource object was not found at the specified virtualPath." error
I have App_LocalResources folders and resx files for each page at the root of the application as well as in sub-folders where page localization is required. Elements on the page that have a meta:resourcekey attribute do not have the relevant property assigned the value in the resx file.
So for example I have: /Site/Home.aspx with a /Site/App_LocalResources/Home folder which contains home.aspx.resx and related translations
N.B. as I was writing this I realised the names don't match up with regards the files case, but that is not the issue, I've tested with another page in the same folder and it doesn't render out the resource values.
The page in question has no code behind.
A different page in the root of the application called PageNotFound.aspx has related resx files in /App_LocalResources/PageNotFound/PageNotFound.aspx.resx
This page content is basically as follows (if I remove both the page renders)
<h2><asp:Literal runat="server" meta:resourcekey="PageNotFound" /></h2>
<% string message = GetLocalResourceObject("Sorry.Template").ToString(); %>
I get the same error whether I remove the first or the second of these lines. The error starts:
System.Resources.MissingManifestResourceException: A resource object was not
found at the specified virtualPath at
System.Web.Compilation.DefaultResourceProvider.GetLocalResourcesAssembly
If I remove the first line is actually builds and tries to render the page but crashes giving the above error.
If I remove the second line I get the error as well but it is while the page is being parsed and the runtime is trying to build the page class.
So for one page is seems build and run with meta:resourcekey attributes but isn't binding the resource value to the properties of the underlying controls, on another page it seems to crash trying to access the resources. The odd thing is the page that crashes is a very simple page without a master page and it basically only has the above content, the other page is quite complex with a master page and it renders (i.e. no parser error) but without the resourcekey values assigned....
The only differences that I can see are that one page is in the root directory and no master page, the other is in a sub folder and has a master page? Go figure! Any ideas?
Issue 2: Resources namespace doesn't exist
If I access a page that uses the 'Resources' namespaces that is available in .NET, I get a runtime compilation error, as in the app builds when compiled, but as the page is parsed and compiled it causes a (runtime) exception...
Compilation Error: CS0103: The name 'Resources' does not exist in the current context
The code would be in the code behind: (EDIT: The following line I think, was me testing, my code never uses this namespace in a code behind (compile time) class. Once the global resources functioned then the namespaces worked at runtime, but not in scenarios where the namespace needs to be verified at compile time as outlined in the summary at the top of the question)
msg.Subject = Resources.EmailResources.Request_SubjectLine
or in a script block in the aspx itself i.e.
<%= Resources.EmailResources.Request_SubjectLine %>
Neither of these types of access to the Resources namespace work. Why does this not work in Mono. Does the Mono framework not generate this stuff for us like .NET does? (I'm fairly sure this namespace hierarchy is generated by the ASP.NET framework on .NET and therefore wonder if this just has not been implemented in Mono?)
Issue 3: GetGlobalResourceObject(...) Call Returns Null
In the code-behind I have calls to GetGlobalResourceObject() which works on .NET, but when I run it on Mono my code is throwing an exception. For example:
hlContact.Text = GetGlobalResourceObject("CommonResources", "Contact").ToString();
My folder structures is:
App_GlobalResources > CommonResources > CommonResources.resx and the designer file (CommonResources.Designer.cs) is there.
The resx files are all marked with build action of "EmbeddedResource", "Do not copy" use the Custom Tool "GlobalResourceProxyGenerator" and have a resource ID that makes sense for each file. (i.e. .App_GlobalResources.CommonResources)
The issue is that GetGlobalResourceObject() returns null... It's not finding the CommonResources resource....
Note that Mono is constructing '*.resource' files in the folder with the resx files.
Issue #1
Apparently mono doesn't search subdirectories for resources, that is you must keep them directly in App_LocalResources or App_GlobalResources. See the relevant part in the mono source code (line 134). If searching subdirectories is an official feature, then this is a bug, and can be easily fixed by changing the aforementioned line.
Issue #2
Works fine here (on linux).
Issue #3
I don't know how exactly you are embedding the resources, a small test project would help. For the App_GlobalResources the framework compiles them at runtime and then GetGlobalResourceObject works fine too.
I have a Page in a Windows Phone class library. This page has an appbar. I would prefer everything this page needs to be included within the class library so the setup list for consumers of this page / assembly is minimal.
However, When I set ApplicationBar icons, they get added to the class library project under the folder 'icons' just like normal, they show up fine in Blend, but at runtime they are no where to be found!
When I put the icons in the Windows Phone Application project all is well. However this is not my desired scenario as it is additional configuration / setup by the application author to use my pages.
I tried using the resource pathing using /{AssemblyName};component/icons/{IconName} but of course the AppBar needs them to be of type "Content" not "Resource". So I am thinking this is impossible but I wanted to know if anybody out there figured out how to do this.
Sorry guys. I just figured it out. I changed the newly added icons from "Resource" to "Content" but I forgot to set "Copy if newer" so they weren't getting outputted to the Bin\Debug\icons folder of the windows Phone Application. something to keep an eye on I guess.
I'm having an issue with the localization in my converters. So, I tried a new project and still have problems.
So, I created a fresh new Silverlight for Windows Phone application (7.0, but 7.1 don't resolve my problem).
I added two resources files: Strings.resx and Strings.fr.resx. This two files have two string property: HelloString and ByeString, all initiated correctly.
Then, I go to the Mainpage.xaml.cs, in the ctor and add the following simple line.
PageTitle.Text = Strings.HelloString;
Whenever I have the emulator or my phone set to English or French, I always got the same strings (Hello).
I tried to rename the file Strings.fr-FR.resx. Still the same issue.
The CurrentUICulture returned from the current thread is correct.
I also tried to force culture on the resource:
Strings.Culture = new System.Globalization.CultureInfo("fr-FR");
Does anyone have an idea?
You don't say that you've set the SupportedCultures for the project. Without this the additional language resource files will never be used.
See http://msdn.microsoft.com/en-us/library/dd941931(v=vs.95).aspx
I've been working on a Windows Phone 7 app, and after a bit of Googling it seems that for images that I have added to the Visual Studio project, I need to set the build action to "Content" in order to be able to reference the images in my app.
However, the Windows Phone List Application project template includes an image (ArrowImg.png) that has its Build Action set to "Resource", and is still available to be referenced from the application.
I was wondering if anyone could confirm that we should definitely be using the Content build action, or whether there is some way to access images added to a project with the Resource Build Action as shown in the project sample, which we should be using instead?
If you set the action to "Content" the image is included "as-is" in the XAP.
If you set the action to "Resource" the image is embedded into a shared DLL.
In a lot of situations you can use either. There may be a performance, or other, issue with using one rather than another but I'm not aware of and have never noticed any.
For what it's worth, unless I need to specifically make it a resource, I use content.
With the current (Beta) tools, I have seen VS complain that images directly referenced in XAML should be set to "Resource" (if set to "Content") but the app works fine with either. Hopefully this is an issue which will be addressed in the RTM tools.
For more information see the discussion in What are the various "Build action" settings in Visual Studio project properties and what do they do?
Either build action is correct.
Also worth looking at when resolving issues relating to build action is the pathing you use.
I've seen a fair few people running into trouble with this because they assume they've set their build action inappropriately.
You can set the build action either way to suit your requirements of when to incur the load time cost, you just need to adjust the pathing to suit.
Some more info on the topic from this post.
Set source to image in C#
You can liken content to the lazy
loading version of resources.
The difference is you will incur the
performance hit of all resources when
the assemblies are loaded to start
your app.
Content, on the other hand, the
performance hit is deferred to when
you use it.
Which is more suitable will vary on a
case by case basis.
Note also that the pathing to
reference resources and content is
different as can see here.
//Uri uri = new Uri("/Resources/Images/MyImage.jpg", UriKind.Relative); // Content
Uri uri = new Uri("/PhoneApp;component/Resources/Images/MyImage.jpg", UriKind.Relative); // Resource
BitmapImage imgSource = new BitmapImage(uri);
image1.Source = imgSource;