3

I have the resource file: Strings\en-US\Resources.resw

I'm trying to bind to a string from this file like so:

<TextBlock Text="{Binding Path=LocalizedResources.app_name, Source={StaticResource LocalizedStrings}}" />

I guess this approach is wrong because I get "The Resource 'TestString' could not be resolved.".

How do I bind to a string from a resource file?


PS: I have TestString in the resource file.

PPS: I need to create Windows 8 store app with Studio 2012, not Windows 8.1 app.

VasileF
  • 2,856
  • 2
  • 23
  • 36
Mit_
  • 149
  • 1
  • 11
  • I have written a Windows Phone 8 app and I was hoping that I can use the same resource files for localization. My bindings there look something like this: Text="{Binding Path=LocalizedResources.app_name, Source={StaticResource LocalizedStrings}}" – Mit_ Jan 15 '14 at 12:59
  • Look at my answer below. Yes, you can use the same localization, but you need some small piece of code. – crea7or Jan 15 '14 at 13:30

4 Answers4

1

There's a tool - PublicResXFileCodeGenerator which you can use to access the resource file values in such a matter :

MyResourceFile.ResourceString;

You can store that value into a property and bind it afterwards on the UI.

EDIT for Binding approach

You'll need a ViewModel which will be set as your DataContext on that View.

Let's say you have three rows with values in your resource file : FirstName, LastName and Age. So you will access them like :

string firstName = MyResourceFile.FirstName;
string lastName = MyResourceFile.LastName;
int age = Convert.ToInt32(MyResourceFile.Age); //made it an int

You will have to create a class which will stand as your ViewModel.

public class MyViewModelClass : INotifyPropertyChanged 
{
    private string firstName;
    public string FirstName
    {
        get { return firstName; }
        set { firstName = value; OnPropertyChanged(); }
    }

    private string lastName;
    public string LastName
    {
        get { return lastName; }
        set { lastName = value; OnPropertyChanged(); }
    }

    private string age;
    public string Age
    {
        get { return age; }
        set { age= value; OnPropertyChanged(); }
    }

    //Also the INotifyProperty members ...
}

Then in the corresponding View code-behind .cs file :

1) Define and declare an instance of the MyViewModelClass.

public MyViewModelClass viewModel = new MyViewModelClass();

2) Set the DataContext to the instance previously set.

this.DataContext = this.viewModel;

3) Add your values from the Resource file :

this.viewModel.FirstName = MyResourceFile.FirstName;
this.viewModel.LastName = MyResourceFile.LastName;
this.viewModel.Age = MyResourceFile.Age;

4) Bind them in your XAML :

<TextBlock Text="{Binding FirstName}" /> 
<TextBlock Text="{Binding LastName}" />
<TextBlock Text="{Binding Age}" />
//The names of the public properties in the View Model class

I'm confused about all this! What do all these things mean?

If you use INotifyPropertyChanged you will be able to update your UI automaticaly when your bound values change. This is because in the setter of each of the properties, there's the OnPropertyChange(); call which will notify your UI of the value changes. OnPropertyChange() call should always be after the values change otherwise, the changes will not be reflected on the UI.

Each page has a DataContext (not only pages, many elements do). From it, you can bind your values using the {Binding something} in your XAML. We're creating an instance of the View Model class, and that instance will be the DataConext for the current page. The binding system will be looking for the corresponding properties names. If they're found the values are shown on the UI. If not, no errors occur, but where you expect a value, nothing will show up.

You can find so many resources of documentation about this pattern, just search for MVVM (Model-View-ViewModel).

VasileF
  • 2,856
  • 2
  • 23
  • 36
  • If you don't manage or don't know how to make the binding, let me know, and I'll tell you, but I advise to search on your own - you will learn better in this way. – VasileF Jan 15 '14 at 10:45
  • 10x. So far so good... now I can access my strings with Resource.StringKey. I also tryed to copy the related code from the Windows Phone 8 app, but failed missarably. The bindings there look like this Text="{Binding Path=LocalizedResources.app_name, Source={StaticResource LocalizedStrings}}" – Mit_ Jan 15 '14 at 13:07
  • You will have to build a View Model, and store the values in some public properties which will be afterwards bound to UI. Made the edit. – VasileF Jan 15 '14 at 20:00
1

You can use same file from the Windows Phone project, but at first, you should move the localization to the PCL - Portable Class Library. You'll use localization in the same way as in Windows Phone in this case. Please, read this tutorial - it's not hard at all.

crea7or
  • 4,421
  • 2
  • 26
  • 37
  • I'm using Visual Studio Express, so this is not an option. – Mit_ Jan 15 '14 at 14:07
  • You have another way with [Multilingual App Toolkit](http://sviluppomobile.blogspot.cz/2013/03/share-localization-files-between.html) or [ResX code generator](https://reswcodegen.codeplex.com/) – crea7or Jan 15 '14 at 14:21
  • Side note: for those who find this solution working but now doesn't after Visual Studio Update 2... there is a bug in VS.u2 that does not recognize Portable Class Libraries that have a "." in the assembly. – Dave Friedel May 30 '14 at 14:06
0

I hava created a method of myown:

1) in App.xaml

<localUtils:ResourceStringConventer x:Key="LocalizedStringsConventer" ></localUtils:ResourceStringConventer>

2) ResourceStringConventer

public class ResourceStringConventer : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {     
        ResourceLoader resourceLoader = new ResourceLoader();
        string text = resourceLoader.GetString((string)parameter);
        return text;
    }
    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

3) The binding

<TextBlock Text="{Binding Converter={StaticResource LocalizedStringsConventer}, ConverterParameter='TestString'}" DataContext="dgsdf" />

The only con that i see is that you have to set the DataContext atribute in the XAML to samething random. I could have put the strings name/key in the DataContext, but this way i wouldn't be able to use the DataContext for its real purpose.

Mit_
  • 149
  • 1
  • 11
0

As you already have a Windows Phone 8 app that uses a resource file, it will be easy to get the same working for your Windows Store app. All you need to do is duplicate the structure in your WinStore app that you have in your WinPhone8 app.

  1. Create a LocatedStrings class in your WinStore app
  2. Copy and paste the contents of that class from the WinPhone to the WinStore
  3. Add a new Resources folder in your app
  4. Add a new Resource file named AppResources. For VS2012+Windows 8 apps, you will find a Resource.resw file. Use this type.
  5. Click the file in the solution Explorer.
  6. Open the Properties Windows and paste 'PublicResXFileCodeGenerator' into the Custom Tool property (without the single quotes)
  7. In App.xaml add the following within the ResourceDictionary element (change the namespace to match your own)
  8. Change the text values in your xaml the same way you have in your Windows Phone 8 app Text="{Binding Path=LocalizedResources.Test, Source={StaticResource LocalizedStrings}}"

Hope that helps!

Shawn Kendrot
  • 12,425
  • 1
  • 25
  • 41