Back to Devexpress

Localizing WinForms Controls with Localizer Objects

windowsforms-1866-build-an-application-localization-localizing-winforms-controls-via-localizer-objects.md

latest20.2 KB
Original Source

Localizing WinForms Controls with Localizer Objects

  • Jun 23, 2025
  • 7 minutes to read

DevExpress WinForms UI controls use Localizer objects to obtain strings for UI elements (for instance, the Data Grid uses GridLocalizer). Localization-related APIs (Localizer objects) take priority over satellite resource assemblies.

Use one of the following methods to modify resources:

  • Implement a custom localizer for a specific UI control.
  • Use the global XtraLocalizer class to localize all DevExpress UI controls.

Note

DevExpress UI controls support two methods of localization: Satellite Resource Assemblies and Localization-Related API (Custom Localizers). There are several UI controls that can only be localized with satellite resource assemblies (for example, the Search dialog in XtraReports).

Custom Localizers

Follow the steps below to create a custom localizer:

  • Create a descendant of a Localizer class that corresponds to a UI control. See the following table for information: Default Localizers.
  • Override the GridLocalizer.GetLocalizedString method to return localized strings for specific resource identifiers.

Tip

You can override the GridLocalizer.PopulateStringTable method to translate specific resources.

  • Assign a custom localizer to the Active property of the Localizer class from which you inherited.

Example - How to Create Custom Localizers

The following example demonstrates how to create localizers to translate resources (menu items) of the Data Grid and Picture Editor into German:

csharp
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraGrid.Localization;

public class GermanGridLocalizer : GridLocalizer {
    public override string Language { get { return "Deutsch"; } }
    public override string GetLocalizedString(GridStringId id) {
        string ret = "";
        switch (id) {
            // ... 
            case GridStringId.GridGroupPanelText: return "Ziehen Sie eine Spaltenüberschrift in diesen Bereich, um nach dieser zu gruppieren";
            case GridStringId.MenuColumnClearSorting: return "Sortierung entfernen";
            case GridStringId.MenuGroupPanelHide: return "Gruppierungsfeld ausblenden";
            case GridStringId.MenuColumnRemoveColumn: return "Spalte entfernen";
            case GridStringId.MenuColumnFilterEditor: return "Filter &bearbeiten";
            case GridStringId.MenuColumnFindFilterShow: return "Suche einblenden";
            case GridStringId.MenuColumnAutoFilterRowShow: return "Zeige Auto Filterzeile";
            case GridStringId.MenuColumnSortAscending: return "Aufsteigend sortieren";
            case GridStringId.MenuColumnSortDescending: return "Absteigend sortieren";
            case GridStringId.MenuColumnGroup: return "Gruppieren fur dieses Feld";
            case GridStringId.MenuColumnUnGroup: return "Gruppierung aufheben";
            case GridStringId.MenuColumnColumnCustomization: return "Laufzeit benutzerdefinierte Spalte";
            case GridStringId.MenuColumnBestFit: return "Optimale Breite";
            case GridStringId.MenuColumnFilter: return "Kann gruppieren";
            case GridStringId.MenuColumnClearFilter: return "Filter aufheben";
            case GridStringId.MenuColumnBestFitAllColumns: return "Optimale Breite (alle Spalten)";
            // ... 
            default:
                ret = base.GetLocalizedString(id);
                break;
        }
        return ret;
    }
}

public class GermanEditorsLocalizer : Localizer {
   public override string Language { get { return "Deutsch"; }}
   public override string GetLocalizedString(StringId id) {
      switch(id) {
         // ...
         case StringId.PictureEditMenuCut: return "Ausschneiden";
         case StringId.PictureEditMenuCopy: return "Kopieren";
         case StringId.PictureEditMenuPaste: return "Einfugen";
         case StringId.PictureEditMenuDelete: return "Loschen";
         case StringId.PictureEditMenuLoad: return "Laden";
         case StringId.PictureEditMenuSave: return "Speichern";
         // ...
      }
      return base.GetLocalizedString(id);
   }
}
vb
Imports DevExpress.XtraEditors.Controls
Imports DevExpress.XtraGrid.Localization

Public Class GermanGridLocalizer
    Inherits GridLocalizer
    Public Overrides ReadOnly Property Language() As String
        Get
            Return "Deutsch"
        End Get
    End Property
    Public Overrides Function GetLocalizedString(id As GridStringId) As String
        Dim ret As String = ""
        Select Case id
            ' ... 
            Case GridStringId.GridGroupPanelText
                Return "Ziehen Sie eine Spaltenüberschrift in diesen Bereich, um nach dieser zu gruppieren"
            Case GridStringId.MenuColumnClearSorting
                Return "Sortierung entfernen"
            Case GridStringId.MenuGroupPanelHide
                Return "Gruppierungsfeld ausblenden"
            Case GridStringId.MenuColumnRemoveColumn
                Return "Spalte entfernen"
            Case GridStringId.MenuColumnFilterEditor
                Return "Filter &bearbeiten"
            Case GridStringId.MenuColumnFindFilterShow
                Return "Suche einblenden"
            Case GridStringId.MenuColumnAutoFilterRowShow
                Return "Zeige Auto Filterzeile"
            Case GridStringId.MenuColumnSortAscending
                Return "Aufsteigend sortieren"
            Case GridStringId.MenuColumnSortDescending
                Return "Absteigend sortieren"
            Case GridStringId.MenuColumnGroup
                Return "Gruppieren fur dieses Feld"
            Case GridStringId.MenuColumnUnGroup
                Return "Gruppierung aufheben"
            Case GridStringId.MenuColumnColumnCustomization
                Return "Laufzeit benutzerdefinierte Spalte"
            Case GridStringId.MenuColumnBestFit
                Return "Optimale Breite"
            Case GridStringId.MenuColumnFilter
                Return "Kann gruppieren"
            Case GridStringId.MenuColumnClearFilter
                Return "Filter aufheben"
            Case GridStringId.MenuColumnBestFitAllColumns
                Return "Optimale Breite (alle Spalten)"
            Case Else
                ' ... 
                ret = MyBase.GetLocalizedString(id)
                Exit Select
        End Select
        Return ret
    End Function
End Class

Public Class GermanEditorsLocalizer
   Inherits Localizer
   Public Overrides ReadOnly Property Language() As String
      Get
         Return "Deutsch"
      End Get
   End Property

   Public Overrides Function GetLocalizedString(ByVal id As StringId) As String
      Select Case id
         ' ...
         Case StringId.PictureEditMenuCut : Return "Ausschneiden"
         Case StringId.PictureEditMenuCopy : Return "Kopieren"
         Case StringId.PictureEditMenuPaste : Return "Einfugen"
         Case StringId.PictureEditMenuDelete : Return "Loschen"
         Case StringId.PictureEditMenuLoad : Return "Laden"
         Case StringId.PictureEditMenuSave : Return "Speichern"
         ' ...
      End Select
      Return MyBase.GetLocalizedString(id)
   End Function
End Class

Assign instances of the GermanGridLocalizer and GermanEditorsLocalizer classes to the GridLocalizer.Active and Localizer.Active properties before application startup to activate custom localizers.

csharp
public Form1() {
    GridLocalizer.Active = new GermanGridLocalizer();
    Localizer.Active = new GermanEditorsLocalizer();
    InitializeComponent();
}
vb
Public Sub Form1()
    GridLocalizer.Active = New GermanGridLocalizer()
    Localizer.Active = New GermanEditorsLocalizer()
    InitializeComponent()
End Sub

Default Localizers

The following table lists default Localizer classes and corresponding resource string identifiers for DevExpress WinForms UI controls:

ControlLocalizer ClassesResource String Identifier (Enum)
Chart ControlChartLocalizer, ChartResLocalizerChartStringId
Data Access LibraryDataAccessUILocalizerDataAccessUIStringId
Data GridGridLocalizer, GridResLocalizerGridStringId
DiagramsDiagramControlLocalizer, DiagramControlResLocalizerDiagramControlStringId
Editors and ControlsLocalizer, EditResLocalizerStringId
GaugesGaugesCoreLocalizerGaugesCoreStringId
Layout and Data Layout ControlsLayoutLocalizer, LayoutResLocalizerLayoutStringId
Navigation BarNavBarLocalizerNavBarStringId
PDF ViewerPdfCoreLocalizer / XtraPdfViewerLocalizer, XtraPdfViewerResLocalizerPdfCoreStringId / XtraPdfViewerStringId
Pivot GridPivotGridLocalizer, PivotGridResLocalizerPivotGridStringId
Printing-ExportingPreviewLocalizer, PreviewResLocalizerPreviewStringId
ReportingReportLocalizer, ReportResLocalizerReportStringId
Ribbon, Bars and MenuBarLocalizer, BarResLocalizer, DocManagerLocalizer,BarString, DocumentManagerLocalizerId
Rich Text EditorXtraRichEditLocalizer, RichEditExtensionsLocalizer / OfficeLocalizer, XtraRichEditResLocalizerXtraRichEditStringId, RichEditExtensionsStringId / OfficeStringId
SchedulerSchedulerLocalizer, SchedulerResLocalizerSchedulerStringId
Spell CheckerSpellCheckerLocalizerSpellCheckerStringId
SpreadsheetXtraSpreadsheetLocalizer, XtraSpreadsheetFunctionNameLocalizer, XtraSpreadsheetCellErrorNameLocalizer, OfficeLocalizer, XtraSpreadsheetResLocalizerXtraSpreadsheetStringId, XtraSpreadsheetFunctionNameStringId, XtraSpreadsheetCellErrorNameStringId / OfficeStringId
Tree ListTreeListLocalizer, TreeListResLocalizerTreeListStringId
Vertical GridVGridLocalizer, VGridResLocalizerVGridStringId
Data FilteringFilterUIElementResXLocalizerFilterUIElementLocalizerStringId
XtraDialogDialogsLocalizerDialogsStringId

Note

Localizer vs ResLocalizer

The XXXLocalizer object uses predefined invariant strings. Non-translated strings override translations in localized resource assemblies. Use the XXXResLocalizer object to translate non-translated strings or modify translated strings in localized resource assemblies.

Tip

Use the DevExpress UI Localization Client to quickly identify non-translated strings of DevExpress UI controls and translate them during a debug session. The UI Localization Client automatically generates required RESX files with translated resources and adds them to the project.

XtraLocalizer - Event Based Localization

The XtraLocalizer class implements a localization-related API that allows you to translate DevExpress UI controls and forms into different languages and develop multicultural enterprise applications:

  • The QueryLocalizedString and QueryLocalizedStringContainerResource events allow you to localize resources for all DevExpress UI controls and their built-in data forms in your application. These events fire when a control or data form requests a resource string. Handle these events to translate or modify resource strings as needed.
  • The QueryLocalizedStringNonTranslated allows you to focus on the strings that require translation in your application. Handle this event to collect non-localized resource strings for further translation.

Note

These events are weak events. You should implement the event handler as a method. Otherwise, the garbage collector can collect a reference to your delegate.

Example

csharp
using System;
using System.Windows.Forms;
using DevExpress.Utils.Localization;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraGrid.Localization;

namespace DXApplication {
    internal static class Program {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            XtraLocalizer.QueryLocalizedString += XtraLocalizer_QueryLocalizedString;
            Application.Run(new Form1());
        }
        static private void XtraLocalizer_QueryLocalizedString(object sender, XtraLocalizer.QueryLocalizedStringEventArgs e) {
            if (e.StringIDType == typeof(GridStringId)) {
                if ((GridStringId)e.StringID == GridStringId.GridGroupPanelText)
                    e.Value = "Gruppenregion";
            }
            if (e.StringIDType == typeof(StringId)) {
                if ((StringId)e.StringID == StringId.PictureEditMenuCut)
                    e.Value = "Ausschneiden";
                if ((StringId)e.StringID == StringId.PictureEditMenuCopy)
                    e.Value = "Kopieren";
                if ((StringId)e.StringID == StringId.PictureEditMenuPaste)
                    e.Value = "Einfugen";
            }
        }
    }
}
vb
Imports System
Imports System.Windows.Forms
Imports DevExpress.Utils.Localization
Imports DevExpress.XtraEditors.Controls
Imports DevExpress.XtraGrid.Localization

Namespace DXApplication
    Friend Module Program
        ''' <summary>
        ''' The main entry point for the application.
        ''' </summary>
        <STAThread>
        Sub Main()
            Application.EnableVisualStyles()
            Application.SetCompatibleTextRenderingDefault(False)
            AddHandler XtraLocalizer.QueryLocalizedString, AddressOf XtraLocalizer_QueryLocalizedString
            Application.Run(New Form1())
        End Sub
        Private Sub XtraLocalizer_QueryLocalizedString(ByVal sender As Object, ByVal e As XtraLocalizer.QueryLocalizedStringEventArgs)
            If e.StringIDType Is GetType(GridStringId) Then
                If CType(e.StringID, GridStringId) Is GridStringId.GridGroupPanelText Then
                    e.Value = "Gruppenregion"
                End If
            End If
            If e.StringIDType Is GetType(StringId) Then
                If CType(e.StringID, StringId) Is StringId.PictureEditMenuCut Then
                    e.Value = "Ausschneiden"
                End If
                If CType(e.StringID, StringId) Is StringId.PictureEditMenuCopy Then
                    e.Value = "Kopieren"
                End If
                If CType(e.StringID, StringId) Is StringId.PictureEditMenuPaste Then
                    e.Value = "Einfugen"
                End If
            End If
        End Sub
    End Module
End Namespace

Tip

You can also use the XtraLocalizer.UserResourceManager property to leverage RESX files with your localization strings:

csharp
XtraLocalizer.UserResourceManager = Localization.myResources.ResourceManager;
vb
XtraLocalizer.UserResourceManager = Localization.myResources.ResourceManager

See Also

Localizing WinForms Controls with Satellite Resource Assemblies