LangLib - WPF localization using Uids

Since version 1.1.0.1 of the LangLib (MultiDB) and v.1.0.0.5 (SQLite) it has had a possibility to use FrameworkElement.Uid for localization.

It's not recommended that you give the x:Uid values to XAML yourself but use a tool to generate them.

The x:Uid values are generated using MSBuild tool. The basic syntax is MSBuild.exe /t:updateuid YourProjectFile.csproj and MSBuild.exe /t:checkuid YourProjectFile.csproj.

The easiest way is to add these commands to application's Pre-build event command line:

 

The Pre-build event command line as text

$(FrameworkDir)\MSBuild.exe /t:updateuid "$(ProjectPath)"
$(FrameworkDir)\MSBuild.exe /t:checkuid "$(ProjectPath)"

 

As seen in my test project there is no x:Uid tags in the XAML yet:

Lets build

Select the application and select Build

 

The Visual Studio IDE immediately notifies that some files in the solution have been changed:

  

 

Lets select the "Yes to All" button.

The build output should look something like this

1>------ Build started: Project: UidTest, Configuration: Debug Any CPU ------
1> Microsoft (R) Build Engine version 4.6.79.0
1> [Microsoft .NET Framework, version 4.0.30319.42000]
1> Copyright (C) Microsoft Corporation. All rights reserved.
1>
1> Build started 3.11.2015 17:01:16.
1> Project "C:\Users\Petteri Kautonen\Documents\Visual Studio 2013\Projects\UidTest\UidTest\UidTest.csproj" on node 1 (updateuid target(s)).
1> UpdateUid:
1> Checking Uids in file 'MainWindow.xaml' ...
1> Checking Uids in file 'App.xaml' ...
1> Uids updated in 2 files.
1> Done Building Project "C:\Users\Petteri Kautonen\Documents\Visual Studio 2013\Projects\UidTest\UidTest\UidTest.csproj" (updateuid target(s)).
1>
1> Build succeeded.
1> 0 Warning(s)
1> 0 Error(s)
1>
1> Time Elapsed 00:00:00.55
1> Microsoft (R) Build Engine version 4.6.79.0
1> [Microsoft .NET Framework, version 4.0.30319.42000]
1> Copyright (C) Microsoft Corporation. All rights reserved.
1>
1> Build started 3.11.2015 17:01:17.
1> Project "C:\Users\Petteri Kautonen\Documents\Visual Studio 2013\Projects\UidTest\UidTest\UidTest.csproj" on node 1 (checkuid target(s)).
1> CheckUid:
1> Checking Uids in file 'MainWindow.xaml' ...
1> Checking Uids in file 'App.xaml' ...
1> Uids valid in 2 files.
1> Done Building Project "C:\Users\Petteri Kautonen\Documents\Visual Studio 2013\Projects\UidTest\UidTest\UidTest.csproj" (checkuid target(s)).
1>
1> Build succeeded.
1> 0 Warning(s)
1> 0 Error(s)
1>
1> Time Elapsed 00:00:00.05

Lets see how the XAML did change:

 

All the FrameworkElement descendants now have an x:Uid value thus they can now be localized by the LangLib.

Disabling the Uid / x:Uid generation while developing

You can use any batch script commands / markings to disable the Uid / x:Uid generation such as echo, rem or ::.

For example echo just echoes the commands before build:

 

And the build result:

This way you can even copy the commands to run them outside the IDE.

The :: mark before a command is a commend so nothing gets echoed. 

 

After this your WPF application can be localize with the DBLangEngine.

Thanks for your interest cool

LangLib MultiDB Instructions

 

Differences between LangLib

The library itself supports SQLite database as default so no code changes are required except for the DBLangEngine.ShoudConfigure() and the DBLangEngine.RunConfigurator();.

These mentioned additions are required only if you wish to use MySQL serverPostgreSQL server or Microsoft SQL server database engines.

The database configuration software (SecureDatabaseSetting) is included in both of the release and the source package of the library.

The SecureDatabaseSetting adapts to the calling software:

  • Uses the icon of the calling software.
  • Mentions the calling software product name in it's title bar, so no code changes are required for this little piece of program.

Command line parameter changes 

The --dbLang or --dbLang=[culture], e.g. --dbLang=fi-FI command line parameter causes the program to "dump" the language items into a configured or not configured database. This will also cause the library to "dump" a list of cultures into a database so the library won't insert a culture list into the database unless this command line parameter is defined.

A command line parameter --configureLang causes the library to execute the SecureDatabaseSetting software to configure a database.

 

The SecureDatabaseSetting

This program should be located in the same directory as your product's executable. This configures a database connection.

The only thing you shouldn't change in this window is the "Save config to:" option, as the LangLib automatically set the path on application initialization.

The "Don't try to create tables..." option prevents the LangLib to try to create non-existent database tables on application start. Manual creation scripts are included in the downloads.

You should test the connection before accepting the database configuration.

The logic how this LangLib MultiDB chooses it's database settings is as follows:

  • If there is no file called [...]\AppData\Local\[Assembly product name]\dbconfig.sqlite the library resets to default SQLite connection, otherwise the connection parameters are read from the previously mentioned file and a database connection is based on those settings in the file.

 

Other differences

The size of the library is of course larger as 3 more databases are supported. I won't be killing the original LangLib library with only SQlite database support.

The DBLocalization software supports these new databases and a script can be made to share these localizations through all the four supported databases.

The rest is quite the same as with the SQLite-only LangLib.

 

Windows Forms

Inheritance from a System.Windows.Forms.Form should be changed as follows:

using VPKSoft.LangLib;

 

namespace WindowsFormsApplication1
{
    public partial class Form1 : DBLangEngineWinforms
    {
        public Form1()
        {
            InitializeComponent();
            DBLangEngine.DBName = "WindowsFormsApplication1.sqlite";
            if (Utils.ShouldLocalize() != null)
            {
                DBLangEngine.InitalizeLanguage("WindowsFormsApplication1.Messages", Utils.ShouldLocalize(), false);
                return; // After localization don't do anything more.
            }


            DBLangEngine.InitalizeLanguage("WindowsFormsApplication1.Messages");

 

WPF / XAML

With WPF the inheritance is a bit more complex procedure, but once done it stays..

using VPKSoft.LangLib;

namespace WPFApplication1
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1: VPKSoft.LangLib.DBLangEngineWPF
    {
        public Window1()
        {
            InitializeComponent();

            DBLangEngine.DBName = "WPFApplication1.sqlite";
            if (Utils.ShouldLocalize() != null)
            {
                DBLangEngine.InitalizeLanguage("WPFApplication1.Messages", Utils.ShouldLocalize(), false);
                return; // After localization don't do anything more.
            }
            DBLangEngine.InitalizeLanguage("WPFApplication1.Messages");

 

After this we need to modify the xaml:

<VPKSoft:DBLangEngineWPF x:Name="Window1" x:Class="WPFApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:VPKSoft="clr-namespace:VPKSoft.LangLib;assembly=VPKSoft.LangLib"
        Title="LangLibTestWPF" Height="309" Width="460" Icon="images/VPKSoft.ico">

 

 

So we link the Langlib library to the xaml by giving it a a xml namespace. NOTE: The namespace does not need to be VPKSoft.

xmlns:VPKSoft="clr-namespace:VPKSoft.LangLib;assembly=VPKSoft.LangLib"

After that we inherit the change the Window1: Window to

VPKSoft:DBLangEngineWPF

Just remember to keep those VPKSoft's as in VPKSoft == VPKSoft..

 

Program.cs

We need to modify this file so that the localization "dump" or database configuration may take place.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using VPKSoft.LangLib;

namespace LangLibTestWinforms
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);


            if (DBLangEngine.ShoudConfigure()) // configure database connection and exit
            {
                DBLangEngine.RunConfigurator();
                return;
            }

            if (Utils.ShouldLocalize() != null) // Localize and exit.
            {
                new FormMain();
                new FormAbout();
                return;
            }
            Application.Run(new FormMain());
        }
    }
}

So we don't let the application to start if a command line parameter --dbLang or --dbLang=cu-RE (ISO 639-1) or --configureLang was given.

 

 

App.xaml.cs 

We need to modify this file so that the localization "dump" or database configuration may take place.

 

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using VPKSoft.LangLib;

namespace LangLibTestWPF
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            if (DBLangEngine.ShoudConfigure()) // Configure database and exit
            {
                DBLangEngine.RunConfigurator();
                System.Diagnostics.Process.GetCurrentProcess().Kill(); // self kill after configuration
                return;
            }

            if (Utils.ShouldLocalize() != null) // Localize and exit.
            {
                new MainWindow();
                new AboutWindow();
                System.Diagnostics.Process.GetCurrentProcess().Kill(); // self kill after localization
                return;
            }
        }
    }
}

 

So with WPF we instruct the application to "kill self" if a command line parameter --dbLang or --dbLang=cu-RE (ISO 639-1) or --configureLang was given. 

 

One embedded resource 

As the was some talk about not needing any resources, a one is required.

This is to store the inside application messages such as a message shown in a MessageBox.

You may name it anything you want. Here is a sample:

 

Just remember to call the LangLib with the right resource name. If your application namespace is for example WindowsFormsApplication1 

you should tell the application to initialize with a the resource name:

DBLangEngine.InitalizeLanguage("WindowsFormsApplication1.Messages");

 

Download as a document

There are to document formats which I will support. One is LibreOffice (.odt) and another is

Portable Document Format (.pdf). If you wish, you can edit the LibreOffice file and send it to me

for an update.

 

That's it

I hope this help file was instructional enough to start localizing. tongue-out

LangLib Instructions

Windows Forms

Inheritance from a System.Windows.Forms.Form should be changed as follows:

using VPKSoft.LangLib;

 

namespace WindowsFormsApplication1
{
    public partial class Form1 : DBLangEngineWinforms
    {
        public Form1()
        {
            InitializeComponent();
            DBLangEngine.DBName = "WindowsFormsApplication1.sqlite";
            if (Utils.ShouldLocalize() != null)
            {
                DBLangEngine.InitalizeLanguage("WindowsFormsApplication1.Messages", Utils.ShouldLocalize(), false);
                return; // After localization don't do anything more.
            }


            DBLangEngine.InitalizeLanguage("WindowsFormsApplication1.Messages");

 

WPF / XAML

With WPF the inheritance is a bit more complex procedure, but once done it stays..

using VPKSoft.LangLib;

namespace WPFApplication1
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1: VPKSoft.LangLib.DBLangEngineWPF
    {
        public Window1()
        {
            InitializeComponent();

            DBLangEngine.DBName = "WPFApplication1.sqlite";
            if (Utils.ShouldLocalize() != null)
            {
                DBLangEngine.InitalizeLanguage("WPFApplication1.Messages", Utils.ShouldLocalize(), false);
                return; // After localization don't do anything more.
            }
            DBLangEngine.InitalizeLanguage("WPFApplication1.Messages");

 

After this we need to modify the xaml:

<VPKSoft:DBLangEngineWPF x:Name="Window1" x:Class="WPFApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:VPKSoft="clr-namespace:VPKSoft.LangLib;assembly=VPKSoft.LangLib"
        Title="LangLibTestWPF" Height="309" Width="460" Icon="images/VPKSoft.ico">

 

 

So we link the Langlib library to the xaml by giving it a a xml namespace. NOTE: The namespace does not need to be VPKSoft.

xmlns:VPKSoft="clr-namespace:VPKSoft.LangLib;assembly=VPKSoft.LangLib"

After that we inherit the change the Window1: Window to

VPKSoft:DBLangEngineWPF

Just remember to keep those VPKSoft's as in VPKSoft == VPKSoft..

 

Program.cs

We need to modify this file so that the localization "dump" may take place.

For Windows Forms

using VPKSoft.LangLib;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            if (Utils.ShouldLocalize() != null) // Localize and exit.
            {
                new Form1();
                return;
            }
            Application.Run(new Form1());
        }
    }
}

So we don't let the application to start if a command line parameter --dbLang or --dbLang=cu-RE (ISO 639-1) was given.

 

For WPF / XAML

using VPKSoft.LangLib;

namespace WPFApplication1
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            if (Utils.ShouldLocalize() != null) // Localize and exit.
            {
                new Window1();
                System.Diagnostics.Process.GetCurrentProcess().Kill(); // self kill after localization
                return;
            }
        }
    }
}

So with WPF we instruct the application to "kill self" if a command line parameter --dbLang or --dbLang=cu-RE (ISO 639-1) was given.

 

One embedded resource 

As the was some talk about not needing any resources, a one is required.

This is to store the inside application messages such as a message shown in a MessageBox.

You may name it anything you want. Here is a sample:

 

Just remember to call the LangLib with the right resource name. If your application namespace is for example WindowsFormsApplication1 

you should tell the application to initialize with a the resource name:

DBLangEngine.InitalizeLanguage("WindowsFormsApplication1.Messages");

 

Download as a document

There are to document formats which I will support. One is LibreOffice (.odt) and another is

Portable Document Format (.pdf). If you wish, you can edit the LibreOffice file and send it to me

for an update.

 

That's it

I hope this help file was instructional enough to start localizing. tongue-out