Resource File Beyond Localization

AgendaUsing Resource file (.resx) to provide customize caption for different users.

Introduction:

Resource file is a great way to provide multilingual web application (not just web application but any other application). This is not just for making multilingual website but enable your application to support complete localization (provide pics etc depends on culture. But wait… What if you get in a situation where you need to support (or provide) some different captions with in the same culture….? So… lets built the solution of this problem.

Couple of months ago our customer demanded to provide them captions they like (or  use frequently in their company) in the application, while this seems to be easy task but it gets difficult when couple of more clients demands the same thing. So we decided to start searching on it as this seems to be the usual case when our application users (our clients grows).

Note: I am developing an Human Resource Application (made on Silverlight 4) which have dozens of clients.

After couple of days of googling I was quite surprised after seeing that no one has actually faced the same issue rather all using Resource file For Localization etc. I got Gerhard Stephan’s this link which guided me towards my solution. So lets get started.

THE SOLUTION:

Step 1:  (Create Silverlight Application)  

First of all create a new Silverlight Application using VS2010 goto File –> New –> Project –> Silverlight –> Silverlight Naviagation Application and name it “ResourceFileBeyondLocalization” and Save it to the desired path. This adds two projects in your solution ResourceFileBeyondLocalization (Silverlight Application) and ResourceFileBeyondLocalization.Web (The ASP.Net hosting application for Silverlight)

Now add two folders Converters and Resources to the Silverlight Application. After this step your solution looks the pic given below Image

Step 3: (Adding Resource Files)

Now, Add one default resource file by right clicking on the Resources folder choose Add New Item –> Select Resource File .resx and name it Captions.resx and two other resource files (Captions_ClientABC.resx & Captions_ClientXYZ.resx) in the same folder i.e. Resources.

Match your work with the picture given below

Image

Step 4: (Adding Captions in Resource File)

Now Open the Captions.resx file and add the captions and Change the Access Modifier shown below

Image

Add captions the the other two files too with the same key(s) as in the first file.

Step 5: (Write a Converter Class)

Now Right Click on the Converters Folder and Add –> Class and name it ApplicationCaptions.cs

public class ApplicationCaptions : IValueConverter
{
private static ResourceManager resourceManger = new ResourceManager("ResourceFileBeyondLocalization.Resources.Captions", Assembly.GetExecutingAssembly());

public static ResourceManager ResourceManager
{
get { return resourceManger; }
set { resourceManger = value; }
}

public string GetCaption(string captionKey)
{
return ResourceManager.GetString(captionKey);
}

#region IValueConverter Implementation

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var reader = (ApplicationCaptions)value;
return reader.GetCaption((string)parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}

Step 6: Register Converter in App.xaml
Define this newly added converter in the App.xaml file to use it in Silverlight Project As shown in the code below
with RED color.

<Application x:Class="ResourceFileBeyondLocalization.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<span style="color: #ff0000;">xmlns:Resources="clr-namespace:ResourceFileBeyondLocalization.Converters;assembly=ResourceFileBeyondLocalization"></span>
 <Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
 <ResourceDictionary Source="Assets/Styles.xaml"/>
</ResourceDictionary.MergedDictionaries>

<span style="color: #ff0000;"><Resources:ApplicationCaptions x:Key="BeyondLocalization"/></span>
 </ResourceDictionary>
 </Application.Resources>
</Application>

Step 7: (Add two Pages and Write some XAML)

Now add two Pages in the in the Views folder and copy the code given below

FOR PAGE 1

<navigation:Page x:Class="ResourceFileBeyondLocalization.Views.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
 d:DesignWidth="640" d:DesignHeight="480"
Title="Page1 Page">
 <Grid x:Name="LayoutRoot">
<TextBlock x:Name="caption1" Text="{Binding ConverterParameter=Caption0001, Converter={StaticResource BeyondLocalization}, Source={StaticResource BeyondLocalization}}" Height="42" HorizontalAlignment="Left" Margin="40,31,0,0" VerticalAlignment="Top" Foreground="BlueViolet" FontSize="20" FontWeight="Bold" Width="347" /> <TextBlock x:Name="caption2"
Text="{Binding ConverterParameter=Caption0002, Converter={StaticResource BeyondLocalization}, Source={StaticResource BeyondLocalization}}" Height="32" HorizontalAlignment="Left" Margin="40,91,0,0" VerticalAlignment="Top" Width="337" Foreground="Chartreuse" FontWeight="SemiBold" FontSize="16" />
 <TextBlock x:Name="caption3" Text="{Binding ConverterParameter=Caption0003, Converter={StaticResource BeyondLocalization}, Source={StaticResource BeyondLocalization}}" Height="23" HorizontalAlignment="Left" Margin="46,148,0,0" VerticalAlignment="Top" Foreground="Coral" FontWeight="ExtraBlack" Width="279" FontSize="18" />
 </Grid>
 </navigation:Page>

FOR PAGE 2 copy same code that was in Page 1.

Step 8: (Writing more xaml  in MainPage)

Now add the following code in the NAVIGATION GRID in the MAINPAGE.xaml

<HyperlinkButton Content="Page 1 For Default Client" Tag="" Height="23" HorizontalAlignment="Left" Margin="10,59,0,0" Name="btnDefaultPage1" VerticalAlignment="Top" Foreground="DarkBlue" Click="GoToPage1" />
 <HyperlinkButton Content="Page 2 For Default Client" Tag="" Height="23" HorizontalAlignment="Left" Margin="25,59,0,0" Name="btnDefaultPage2" VerticalAlignment="Top" Foreground="DarkBlue" Click="GoToPage2" />

<HyperlinkButton Content="Page 1 For Client 1" Tag="<span style="color: #0000ff;">_ClientABC</span>" Height="23" HorizontalAlignment="Center" Margin="50,59,0,0" Name="btnClient1Page1" VerticalAlignment="Top" Foreground="Brown" Click="GoToPage1" />
<HyperlinkButton Content="Page 2 For Client 1" Tag="<span style="color: #0000ff;">_ClientABC</span>" Height="23" HorizontalAlignment="Center" Margin="25,59,0,0" Name="btnClient1Page2" VerticalAlignment="Top" Foreground="Brown" Click="GoToPage2" />

<HyperlinkButton Content="Page 1 For Client 2" Tag="<span style="color: #0000ff;">_ClientXYZ</span>" Height="23" HorizontalAlignment="Right" Margin="50,59,0,0" Name="btnClient2Page1" VerticalAlignment="Top" Foreground="DarkGreen" Click="GoToPage1" />
 <HyperlinkButton Content="Page 2 For Client 2" Tag="<span style="color: #0000ff;">_ClientXYZ</span>" Height="23" HorizontalAlignment="Right" Margin="25,59,0,0" Name="btnClient2Page2" VerticalAlignment="Top" Foreground="DarkGreen" Click="GoToPage2" />
 </StackPanel>

Note: The Tags in the code above passes the client. This is just for understanding however you can get the user from Silverlight Cookie in HtmlPage.Document.Cookie property after making log in feature in your application

Step 9: (Wrting Csharp Code to Naviagate between Pages and Change resource)

Final Step is to write code for GoToPage1 and GotoPage2 event handlers. So write the following code in MainPage.xaml.cs

private void GoToPage1(object sender, RoutedEventArgs e)
 {
 ChangeResource(sender);
this.ContentFrame.Navigate(new Uri("/Page1", UriKind.Relative));
 }

private void GoToPage2(object sender, RoutedEventArgs e)
 {
ChangeResource(sender);
 this.ContentFrame.Navigate(new Uri("/Page2", UriKind.Relative));
 }

Step 10: Changing the Resource File at Runtime

private void ChangeResource(object sender)
 {
 var hypBtn = sender as HyperlinkButton;
string applicationCaptionFileName = "ResourceFileBeyondLocalization.Resources.Captions";

switch (hypBtn.Tag.ToString().Trim().ToUpper())
 {
 case "_CLIENTABC":
 applicationCaptionFileName = "ResourceFileBeyondLocalization.Resources.Captions" + hypBtn.Tag.ToString().Trim();
 break;

case "_CLIENTXYZ":
 applicationCaptionFileName = "ResourceFileBeyondLocalization.Resources.Captions" + hypBtn.Tag.ToString().Trim();
 break;

default:
break;
 }

ApplicationCaptions.ResourceManager = new System.Resources.ResourceManager(applicationCaptionFileName, Assembly.GetExecutingAssembly());
 this.Resources.Remove("BeyondLocalization");
 this.Resources.Add("BeyondLocalization", new ApplicationCaptions());
this.ContentFrame.Refresh();
}

Running the Application

ResourceFileDefault

Now Select Page 1 For Client 1 (i.e. ABC)

ResourceFileCustomize

Enjoy Coding…!!! :p

Follow

Get every new post delivered to your Inbox.