Localization in Xamarin Pdf Viewer (SfPdfViewer)
21 Feb 202416 minutes to read
Localization is the process of configuring the application to a specific language. PdfViewerControl supports to localize its static text. SfPdfViewer uses the following static text that can be localized in application level:
Keyword | Text(English) |
---|---|
SfPdfViewerCancel | Cancel |
SfPdfViewerCopy | Copy |
SfPdfViewerHighlight | Highlight |
SfPdfViewerHyperlinkCancel | Cancel |
SfPdfViewerHyperlinkMessage | Do you want to open the webpage |
SfPdfViewerHyperlinkMessageTitle | Open web page |
SfPdfViewerHyperlinkOpen | Open |
SfPdfViewerInvalidPageMessage | Invalid Page Number |
SfPdfViewerInvalidPageMessageTitle | Error |
SfPdfViewerNoMatches | No matches were found |
SfPdfViewerNoOccurrences | No more matches were found |
SfPdfViewerOkMessage | Ok |
SfPdfViewerPageEntryCancel | Cancel |
SfPdfViewerPageEntryOkay | Ok |
SfPdfViewerPageNumberEntryMessage | Enter Page Number |
SfPdfViewerPageNumberEntryMessageTitle | Go To Page |
SfPdfViewerPlaceHolderText | Type your text |
SfPdfViewerRedo | Redo |
SfPdfViewerSave | Save |
SfPdfViewerSearchResult | Search Result |
SfPdfViewerStrikethrough | Strikethrough |
SfPdfViewerUnderline | Underline |
SfPdfViewerUndo | Undo |
SfPdfViewerSignaturePadTitle | Create Signature |
SfPdfViewerDone | Done |
SfPdfViewerClear | Clear |
SfPdfViewerSignatureCancel | Cancel |
SfPdfViewerSearchPlaceHolderText | Enter text to search |
SfPdfViewerBookmarkToolbarTitle | Bookmarks |
SfPdfViewerNoBookmarksText | No Bookmarks |
SfPdfViewerPrint | |
SfPdfViewerContinuousPage | Continuous Pages |
SfPdfViewerPageByPage | Page By Page |
SfPdfViewerOfMessage | Of |
SfPdfViewerSubmit | Submit |
SfPdfViewer_PageNavigationDialog_OfPages | of pages |
SfPdfViewerPageNumberEntryMessageTitleMaterial | Go to Page |
SfPdfViewerBookmarkToolbarTitleMaterial | Bookmark |
SfPdfViewerSignaturePadTitleMaterial | Create Signature |
SfPdfViewerDoneMaterial | DONE |
SfPdfViewerClearMaterial | CLEAR |
SfPdfViewerSubmitMaterial | SUBMIT |
SfPdfViewerCancelMaterial | CANCEL |
SfPdfViewerPrintAlertErrorTitle | Error |
SfPdfViewerPrintAlertErrorMessage | Password protected document cannot be printed. |
SfPdfViewerClose | Close |
SfPdfViewerSquiggly | Squiggly |
SfPdfViewerApply | Apply |
SfPdfViewerNoBookmarksText | No Bookmarks |
SfPdfViewerEditLabelHeaderText | Rename |
SfPdfViewerLoadingBookmarksText | Loading.... |
SfPdfViewerOkButton | OK |
SfPdfViewerCancelButton | Cancel |
SfPdfViewerPasswordDialogerrorMessage | Invalid Password! |
SfPdfViewerPasswordDialogTitle | Enter Password |
SfPdfViewerPasswordDialogMessage | Enter the password to open this PDF File. |
SfPdfViewerPasswordDialogPlaceholderText | Password |
SfPdfViewerXFAErrorAlertTitle | XFA Forms PDF |
SfPdfViewerXFAErrorAlertMessage | The PDF contains XFA Forms which cannot be viewed in PDF Viewer. |
SfPdfViewerUnhandledConditionErrorAlertTitle | Error loading PDF |
SfPdfViewerUnhandledConditionErrorAlertMessage | There was an error in loading the PDF |
Sfpdfviewer_hinttext | Double Tap to activate |
Sfpdfviewer_signaturebutton | Signature |
Sfpdfviewer_textmarkupsbutton | Text mark-ups |
Sfpdfviewer_inkbutton | Ink |
Sfpdfviewer_freetextbutton | Text |
Sfpdfviewer_shapesbutton | Shapes |
Sfpdfviewer_annotationsbackbutton | Annotations Back |
Sfpdfviewer_fontsizebutton | Font Size |
Sfpdfviewer_textbackbutton | Text Back |
Sfpdfviewer_inkbackbutton | Ink Back |
Sfpdfviewer_thicknessbutton | Thickness |
Sfpdfviewer_colorbutton | Color |
Sfpdfviewer_nextlevelbookmarksbutton | Next level bookmarks |
Sfpdfviewer_previouslevelbookmarksbutton | Previous level bookmarks |
Sfpdfviewer_bookmarksbackbutton | Bookmarks Back |
Sfpdfviewer_annotationsbutton | Annotations |
Sfpdfviewer_opacitybutton | Opacity |
Sfpdfviewer_cyancolorbutton | Cyan |
Sfpdfviewer_magentacolorbutton | Magenta |
Sfpdfviewer_blackcolorbutton | Black |
Sfpdfviewer_redcolorbutton | Red |
Sfpdfviewer_greencolorbutton | Green |
Sfpdfviewer_yellowcolorbutton | Yellow |
Sfpdfviewer_deletebutton | Delete |
Sfpdfviewer_undobutton | Undo |
Sfpdfviewer_continuouspagebutton | Continuous Page |
Sfpdfviewer_singlepagebutton | Single Page |
Sfpdfviewer_redobutton | Redo |
Sfpdfviewer_savebutton | Save |
Sfpdfviewer_printbutton | |
Sfpdfviewer_searchnextbutton | Search Next |
Sfpdfviewer_searchpreviousbutton | Search Previous |
Sfpdfviewer_cancelsearchbutton | Cancel Search |
Sfpdfviewer_searchbackbutton | Search Back |
Sfpdfviewer_searchbarplaceholdertext | Search Bar |
Sfpdfviewer_clearsearchbutton | Clear Search |
Sfpdfviewer_rectanglebutton | Rectangle |
Sfpdfviewer_ellipsebutton | Ellipse |
Sfpdfviewer_polygonbutton | Polygon |
Sfpdfviewer_polylinebutton | Polyline |
Sfpdfviewer_cloudbutton | Cloud |
Sfpdfviewer_linebutton | Line |
Sfpdfviewer_arrowbutton | Arrow |
Sfpdfviewer_shapesbackbutton | Shapes Back |
Sfpdfviewer_rectanglebackbutton | Rectangle Back |
Sfpdfviewer_arrowbackbutton | Arrow back |
Sfpdfviewer_linebackbutton | Line back |
Sfpdfviewer_ellipsebackbutton | Ellipse back |
Sfpdfviewer_highlightbutton | Highlight Text |
Sfpdfviewer_underlinebutton | Underline Text |
Sfpdfviewer_squigglybutton | Squiggly Text |
Sfpdfviewer_textmarkupsbackbutton | Text Markups Back |
Sfpdfviewer_strikethroughbutton | Strikethrough Text |
Sfpdfviewer_highlighttextbackbutton | Text Highlight Back |
Sfpdfviewer_underlinetextbackbutton | Text Underline back |
Sfpdfviewer_strikethroughtextbackbutton | Text strikethrough back |
Sfpdfviewer_searchbutton | Search |
Sfpdfviewer_moreoptionsbutton | More Options |
Sfpdfviewer_bookmarksbutton | Bookmarks |
Sfpdfviewer_viewmodebutton | View Mode |
Sfpdfviewer_redoinkbutton | Redo Ink |
Sfpdfviewer_undoinkbutton | Undo Ink |
Sfpdfviewer_UndoEraserButton | Undo Eraser |
Sfpdfviewer_RedoEraserButton | Redo Eraser |
Sfpdfviewer_done | Done |
Sfpdfviewer_thicknessonebutton | Thickness One |
Sfpdfviewer_thicknesthreebutton | Thickness Three |
Sfpdfviewer_thicknessfivebutton | Thickness Five |
Sfpdfviewer_thicknesssevenbutton | Thickness Seven |
Sfpdfviewer_thicknessninebutton | Thickness Nine |
Sfpdfviewer_cancel | Cancel |
Sfpdfviewer_signaturepad_done | Done |
Sfpdfviewer_signaturepad_cancel | Cancel |
Sfpdfviewer_signaturepad_clear | Clear |
Sfpdfviewer_backbutton | Back |
Sfpdfviewer_bookmarksclosebutton | Close Bookmarks |
Sfpdfviewer_pageupbutton | Previous Page |
Sfpdfviewer_pagedownbutton | Next Page |
Sfpdfviewer_continuousButton | continuous ViewMode |
Sfpdfviewer_singlePageViewButton | SinglePage ViewMode |
Sfpdfviewer_popupbutton | Popup |
Sfpdfviewer_eraserbutton | Eraser |
Sfpdfviewer_popupiconselectorbutton | Popup Icon Selector |
Sfpdfviewer_commentbutton | Comment Icon |
Sfpdfviewer_notebutton | Note Icon |
Sfpdfviewer_insertbutton | Insert Icon |
Sfpdfviewer_keybutton | Key Icon |
Sfpdfviewer_paragraphbutton | Paragraph Icon |
Sfpdfviewer_newparagraphbutton | New Paragraph Icon |
Sfpdfviewer_helpbutton | Help Icon |
Sfpdfviewer_custombookmarkoptionbutton | Custom bookmark option |
To localize the SfPdfViewer, follow the steps in application level:
- Add a .resx file.
- Convert the platform specific language format to .NET format.
- Apply the converted format.
Add a .resx file
In the portable project of your application, add a .resx
file inside the resources folder with Build Action -> EmbeddedResource. File name should be Syncfusion control's Namespace + language code
format.
For example, to set the culture as French, the file should be named as Syncfusion.SfPdfViewer.XForms.fr-FR.resx.
Based on the language, set the appropriate equivalent text to the static text in the .resx file.
NOTE
You should create and add separate .resx files for individual languages.
Convert the platform specific language format to .NET format
To get the localized text from the added .resx
file, declare an interface named ILocalize in your PCL project and implement the interface in each platform renderer. This will query the language set in the device using platform specific code and convert to .NET format.
Refer to the following code snippet to declare the interface in PCL project.
public interface ILocalize
{
CultureInfo GetCurrentCultureInfo();
void SetLocale(CultureInfo cultureInfo);
}
public class PlatformCulture
{
public PlatformCulture(string platformCultureString)
{
if (!String.IsNullOrEmpty(platformCultureString))
{
PlatformString = platformCultureString.Replace("_", "-");// .NET expects dash, not underscore
var dashIndex = PlatformString.IndexOf("-", StringComparison.Ordinal);
if (dashIndex > 0)
{
var parts = PlatformString.Split('-');
LanguageCode = parts[0];
LocaleCode = parts[1];
}
else
{
LanguageCode = PlatformString;
LocaleCode = "";
}
}
}
public string PlatformString
{
get; private set;
}
public string LanguageCode
{
get; private set;
}
public string LocaleCode
{
get; private set;
}
public override string ToString()
{
return PlatformString; ;
}
}
Refer to the following code to implement the interface in Android renderer project.
public class Localize : ILocalize
{
public void SetLocale(CultureInfo cultureInfo)
{
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
}
public CultureInfo GetCurrentCultureInfo()
{
var netLanguage = "en";
var androidLocale = Java.Util.Locale.Default;
netLanguage = AndroidToDotnetLanguage(androidLocale.ToString().Replace("_", "-"));
// this gets called a lot - try/catch can be expensive so consider caching or something
CultureInfo cultureInfo = null;
try
{
cultureInfo = new CultureInfo(netLanguage);
}
catch
{
// iOS locale not valid .NET culture (eg. "en-ES" : English in Spain)
// fallback to first characters, in this case "en"
try
{
var fallback = ToDotnetFallbackLanguage(new PlatformCulture(netLanguage));
cultureInfo = new CultureInfo(fallback);
}
catch
{
// iOS language not valid .NET culture, falling back to English
cultureInfo = new CultureInfo("en");
}
}
return cultureInfo;
}
private string AndroidToDotnetLanguage(string androidLanguage)
{
var netLanguage = androidLanguage;
//certain languages need to be converted to CultureInfo equivalent
switch (androidLanguage)
{
case "ms-BN": // "Malaysian (Brunei)" not supported .NET culture
case "ms-MY": // "Malaysian (Malaysia)" not supported .NET culture
case "ms-SG": // "Malaysian (Singapore)" not supported .NET culture
netLanguage = "ms"; // closest supported
break;
case "in-ID": // "Indonesian (Indonesia)" has different code in .NET
netLanguage = "id-ID"; // correct code for .NET
break;
case "gsw-CH": // "Schwiizertüütsch (Swiss German)" not supported .NET culture
netLanguage = "de-CH"; // closest supported
break;
// add more application-specific cases here (if required)
// ONLY use cultures that have been tested and known to work
}
return netLanguage;
}
private string ToDotnetFallbackLanguage(PlatformCulture platformCulture)
{
var netLanguage = platformCulture.LanguageCode; // use the first part of the identifier (two chars, usually);
switch (platformCulture.LanguageCode)
{
case "gsw":
netLanguage = "de-CH"; // equivalent to German (Switzerland) for this app
break;
// add more application-specific cases here (if required)
// ONLY use cultures that have been tested and known to work
}
return netLanguage;
}
}
Refer to the following code to implement the interface in iOS renderer project.
public class Localize : ILocalize
{
public void SetLocale(CultureInfo cultureInfo)
{
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
}
public CultureInfo GetCurrentCultureInfo()
{
var netLanguage = "en";
if (NSLocale.PreferredLanguages.Length > 0)
{
var pref = NSLocale.PreferredLanguages[0];
netLanguage = iOSToDotnetLanguage(pref);
}
// this gets called a lot - try/catch can be expensive so consider caching or something
CultureInfo cultureInfo = null;
try
{
cultureInfo = new CultureInfo(netLanguage);
}
catch
{
// iOS locale not valid .NET culture (eg. "en-ES" : English in Spain)
// fallback to first characters, in this case "en"
try
{
var fallback = ToDotnetFallbackLanguage(new PlatformCulture(netLanguage));
cultureInfo = new CultureInfo(fallback);
}
catch
{
// iOS language not valid .NET culture, falling back to English
cultureInfo = new CultureInfo("en");
}
}
return cultureInfo;
}
private string iOSToDotnetLanguage(string iOSLanguage)
{
var netLanguage = iOSLanguage;
//certain languages need to be converted to CultureInfo equivalent
switch (iOSLanguage)
{
case "ms-MY": // "Malaysian (Malaysia)" not supported .NET culture
case "ms-SG": // "Malaysian (Singapore)" not supported .NET culture
netLanguage = "ms"; // closest supported
break;
case "gsw-CH": // "Schwiizertüütsch (Swiss German)" not supported .NET culture
netLanguage = "de-CH"; // closest supported
break;
// add more application-specific cases here (if required)
// ONLY use cultures that have been tested and known to work
}
return netLanguage;
}
private string ToDotnetFallbackLanguage(PlatformCulture platCulture)
{
var netLanguage = platCulture.LanguageCode; // use the first part of the identifier (two chars, usually);
switch (platCulture.LanguageCode)
{
//
case "pt":
netLanguage = "pt-PT"; // fallback to Portuguese (Portugal)
break;
case "gsw":
netLanguage = "de-CH"; // equivalent to German (Switzerland) for this app
break;
// add more application-specific cases here (if required)
// ONLY use cultures that have been tested and known to work
}
return netLanguage;
}
}
Implementation of the interface is not required for UWP project, since the resources automatically recognizes the selected language.
Apply the converted format
After setting the root/main page of the application in your MainPage.Xaml.cs file of the PCL project, initialize a new instance of the ResourceManager
class and set it to the PdfViewerResourceManager.Manager
property to look up into the resources with specified root name in the given assembly. Using DependencyService
, call SetLocale()
of the implemented interface with necessary language code as parameter.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
//The PDF is in the Assets folder of this project. Read it into a stream
Stream stream = typeof(App).GetTypeInfo().Assembly.GetManifestResourceStream("GettingStarted.Assets.Xamarin_Forms_Succinctly.pdf");
//Load the stream to PdfViewer
pdfViewerControl.LoadDocument(stream);
//Assign the localized string to the specific culture
PdfViewerResourceManager.Manager=new ResourceManager("GettingStarted.Resources.Syncfusion.SfPdfViewer.XForms", GetType().GetTypeInfo().Assembly);
}
}
For Android and iOS, it is mandatory to implement the previous steps. However, to set the specific language to the application irrespective of the selected language in the device, use CultureInfo.CurrentUICulture
in a specific project of UWP platform.
Refer to the following code example to localize the text in UWP platform.
MainPage.Xaml.cs
public MainPage()
{
this.InitializeComponent();
SfPdfViewerRenderer.Init();
// Applying localization for UWP
CultureInfo.CurrentUICulture = new CultureInfo("fr");
LoadApplication(new GettingStarted.App());
}
NOTE
You can refer to our Xamarin PDF Viewer feature tour page for its groundbreaking feature representations. You can also explore our Xamarin.Forms PDF Viewer example to knows the functionalities of each feature.