Search

Silverlight/WP7 Resource Files and Binding by Jeff Winn

Active

3
0
Sign in
to vote
Type: Suggestion
ID: 628281
Opened: 12/3/2010 8:18:05 PM
Access Restriction: Public
1
Workaround(s)
I was looking into binding xaml directly to a resource file which contains generated code from resgen.exe rather than having to build my own class to access the resource strings. At a minimum this suggestion would affect both Silverlight and Windows Phone 7 development.

Basically, the issue is the Resgen tool included with the Windows SDK creates an internal constructor on the designer code it generates even though the class has been marked public. Since the class constructor is internal, it cannot be added directly to a xaml resource dictionary as shown below...

<Application x:Class="SilverlightApplication1.App" xmlns:local="SilverlightApplication1">
    <Application.Resources>
        <ResourceDictionary>
            <local:AppResources x:Key="LocalizedStrings"/>
        </ResourceDictionary>
    </Application.Resources>

Assuming in my above example, the resx file I added to my project was called AppResources.resx any attempt will result in AG_E_PARSER_UNKNOWN_TYPE exception to be thrown once the App.xaml is parsed.

One way around this problem is to use App.xaml.cs to manually create the instance in the App class constructor like so:

this.Resources.Add("LocalizedStrings", new SilverlightApplication1.AppResources());

However, while this approach works during runtime you will not be able to see anything during design time within Visual Studio.

My suggestion is to make the constructor from the generated code public if the public access modifier has been used. Although making it public for an internal class would have no effect, so the constructor could be made public permanently.
Details (expand)

Visual Studio/Silverlight/Tooling version

Visual Studio 2010

What category (if any) best represents this feedback?

 

Steps to reproduce

I was considering writing up a full list of steps to reproduce the issue, however I found this webpage which provides a perfect example and is well documented:

http://www.c-sharpcorner.com/UploadFile/pchandraker/1066/

Product Language

English

Operating System

Windows 7

Operating System Language

English

Actual results

An exception of type System.Windows.Markup.XamlParseException is thrown with the message AG_E_PARSER_UNKNOWN_TYPE.

Expected results

An exception should not be thrown, the strings should be visible during design-time with Visual Studio, and available at runtime.
File Attachments
File Name Submitted By Submitted On File Size  
SilverlightApplication1.zip 12/4/2010 10 KB
Sign in to post a comment.
Posted by Jeff Winn on 1/6/2011 at 2:35 PM
Ah, I wasn't aware of it already being out there. I know I searched for it before I spent the time to create this one.

However, after reading feedback from the other item it would be nice if we'd get a reason behind the design decision this time other than just closing it. If the logic is valid, I can see why... but it's not like they owe us an explanation for anything. I'm just curious why it'd be a design decision to keep the constructor internal.
Posted by StefanBeck on 12/28/2010 at 2:58 AM
BTW, this is a duplicated report:

https://connect.microsoft.com/VisualStudio/feedback/details/525606/publicresxfilecodegenerator-generates-a-constructor-with-an-internal-access-modifier-instead-of-public?wa=wsignin1.0

However, the solution "by Design" is not sufficient for all scenarios for different reasons:

1) Silverlight / WP7 cannot bind to static members in WPF.
2) The compiler message which is generated is not clear: "XmlParse Exception AG_E_PARSER_UNKNOWN_TYPE". People spend hours to figure out that this error is related to the resx files.

I've seen microsoft evangelists at several conferences (TechEd, Shape,..) during the last 4 years and its always funny to hear them explain "Now, we need to open the resx file and change the constructor from internal to public" when they talk about L10N.

Sure, there is a work-around available, but forums are full of exactly this question.
Posted by Jeff Winn on 12/4/2010 at 10:04 PM
I made an example Silverlight 4 solution in Visual Studio 2010 demonstrating the usage of the generated files with a simple view. The file has been attached, but isn't available (yet).
Posted by Microsoft on 12/3/2010 at 8:23 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.
Posted by Jeff Winn on 12/4/2010 at 10:11 PM
1) Go into the generated designer file and manually change the constructor to public anytime any string resources are added to the main resx file. This is an easy but tedious approach, and often forgot when adding new strings.

2) Expose a property somewhere that the view can bind to, and return the data from the resource property. This will be less work for smaller usage of localized strings, however if your view has quite a few localized strings, this can get rather irritating. One benefit from this approach would be the ability to change the app culture for a view during runtime without having to instantiate a new instance.