Skip to main content

Localizing WinForms Controls via Satellite Resource Assemblies

  • 5 minutes to read

This document demonstrates the most common approach to localizing a .NET application using Satellite Resource Assemblies (libraries that contain translated resources). These assemblies are the standard localization mechanism provided by the .NET Framework, to build multi-language applications. Refer to the Localizing Applications topic in MSDN to learn more about localization.


You can also use a custom localizer to translate the application, but there are controls that only satellite assemblies can translate (for example, the Search dialog in XtraReports). We recommend that you use satellite assemblies to translate the application. Also, note that satellite assemblies are ignored if you use a custom localizer.

This document consists of the following sections.

Obtaining Satellite Assemblies

In most cases, it is not necessary to manually translate all language-specific resources, because DevExpress provides satellite assemblies for a variety of languages and cultures.

The .NET Products Installer includes resource assemblies for certain languages (DE, ES, JA). These resources are not installed by default. You can install them at your discretion.

Note: localized resources may be incomplete. Navigate to the DevExpress Localization Service to download community sourced localization for other languages. This service allows you to modify the existing translations, and compile and download the satellite assemblies.


Refer to the Localization Service documentation for more information on how to prepare and download resource assemblies.

Watch Video


Ensure that the major version of the satellite assemblies (for instance, v22.2) matches the major version of DevExpress libraries in the project.


See the Language Identifier Constants and Strings topic in MSDN to learn about culture identifiers.

Adding Satellite Assemblies to Your Application

Copy the folder(s) (for example, es) that contain satellite assemblies to the application’s EXE file directory.

For example, to include German assemblies, copy the folder named de from the \Bin\Framework\ directory to the directory of your application’s EXE file (usually the bin\Debug\ subdirectory). You can change the Output path project to select another location.



Satellite assemblies must be placed in the folder whose name matches the culture name these assemblies target. For example, if satellite assemblies target the neutral German culture (“de”) they must be placed in the “de” folder (not “de-DE” or any other folder).

The following diagram illustrates where to place satellite assemblies within your application’s directory:



Instead of copying satellite assemblies into the application’s folder, it is also possible to install them to the GAC. Note that if there are different resource assemblies with the same name - one located near the application EXE file and another installed in the GAC - the assembly from the GAC will have a higher priority.

Deploy the application along with satellite assemblies to an end-user’s machine. When launched, the program automatically determines the operating system’s culture, loads corresponding resource assemblies and translates the display text accordingly.

The following images demonstrate Print Preview and Report Designer forms localized into German.



Selecting a Culture Different from the System Culture

Assign the required culture’s abbreviation to the CurrentThread.CurrentUICulture and CurrentThread.CurrentCulture properties to manually specify the culture for an application (regardless of the target operating system).

Note that while you can use a short culture abbreviation (a neutral culture) for the CurrentUICulture property (e.g., “de”), the CurrentCulture property needs to be set a specific culture (e.g., “de-DE”).

The following sample code sets German regional settings for an application.

using System.Globalization;
using System.Threading;
// ...

static void Main() {
    // Create a new object, representing the German culture. 
    CultureInfo culture = CultureInfo.CreateSpecificCulture("de-DE");

    // The following line provides localization for the application's user interface. 
    Thread.CurrentThread.CurrentUICulture = culture;

    // The following line provides localization for data formats. 
    Thread.CurrentThread.CurrentCulture = culture;

    // Set this culture as the default culture for all threads in this application. 
    // Note: The following properties are supported in the .NET Framework 4.5+
    CultureInfo.DefaultThreadCurrentCulture = culture;
    CultureInfo.DefaultThreadCurrentUICulture = culture;

    // Note that the above code should be added BEFORE calling the Run() method.
    Application.Run(new Form1());


If you intend to allow end-users to select from multiple predefined cultures, execute this code before the form is loaded. Although it is possible to assign the CurrentCulture and CurrentUICulture properties on the fly, there is no common method to reload all resources.


My application is not localized.

To use satellite resource assemblies, place them in the appropriate locations, so that they can easily be found by the Common Language Runtime (CLR). In some cases, the application may not be able to locate the satellite assemblies. If this is the case, you can check to see where it looks for assemblies using the standard .NET Fuslogvw.exe utility. Read the following topics in MSDN to learn more:

Some items in my application are not localized.

This may occur because satellite assemblies for a particular culture are not complete. You can translate the missing strings via the DevExpress Localization Service. Refer to the Localization Service documentation to learn more.

My security permissions prohibit running the application.

SecurityPermission must be set to ControlThread to change the culture of Thread.CurrentThread. Note that manipulating threads, however, is dangerous, because of the security state associated with threads. Therefore, permission should only be given to trustworthy code, and only when necessary. The application cannot change the thread culture in semi-trusted code (see the CultureInfo.CurrentCulture property description in MSDN for details).