Files
Christoph Schwörer f045b99a25 Codebasis als Dateien ins Arbeitsrepo statt als Gitlink
QuellCode/CentronERP war nur als Gitlink (Submodul-Referenz auf 79c1142)
getrackt, ohne .gitmodules und ohne erreichbares Remote. Der
Untersuchungsgegenstand der Versuchsreihe war damit nicht reproduzierbar
gesichert: Ein Klon haette ein leeres Verzeichnis erhalten, und die Belege
der 3.287 Anforderungen waeren nicht ueberpruefbar gewesen.

Umstellung:
- Historie nach c:\DEV\CentronERP_git_snapshot_79c1142 ausgelagert
  (vollstaendig lesbar, enthaelt 79c1142 und Vorgaenger 89ccfd6)
- Gitlink aus dem Index entfernt
- Dateiinhalt aufgenommen: 24.557 Dateien, rund 333 MB

Die verschachtelte .gitignore der Codebasis gilt weiter, Build-Artefakte
bleiben ausgeschlossen. Details in Versuche/Versuch_01/_Codebasis-Nachweis.md
2026-08-26 07:43:51 +02:00

11 KiB

Localization

General structure

We use the .NET default approach for the localization. Each DLL which needs localized strings, adds the necessary resource files. The used language is determined by CultureInfo.CurrentUICulture.

Resource Files Structure

The application has separate resource files for different layers and supports multiple languages:

WPF UI Layer:

  • German (default): src/centron/Centron.WPF.UI/Resources/LocalizedStrings.resx
  • English: src/centron/Centron.WPF.UI/Resources/LocalizedStrings.en.resx

Business Logic Layer:

  • German (default): src/backend/Centron.BL/Resources/LocalizedStrings.resx
  • English: src/backend/Centron.BL/Resources/LocalizedStrings.en.resx

Language Support

  • Default Language: German - stored in the base resource files (LocalizedStrings.resx)
  • Additional Languages: English - stored in language-specific resource files (LocalizedStrings.en.resx)
  • Language Selection: Determined by CultureInfo.CurrentUICulture

Each resource file contains the same keys but with text in the respective language. When creating new localized strings, you must provide translations for both German and English.

Example of the same key in different languages:

German (LocalizedStrings.resx):
LoginDialogView_Benutzername = "Benutzername"

English (LocalizedStrings.en.resx):
LoginDialogView_Benutzername = "Username"

Usage Examples

XAML Usage

In XAML files, localized strings are accessed using static property syntax with the appropriate namespace declaration.

Namespace Declaration: Add this to your XAML file's root element:

xmlns:properties="clr-namespace:CentronSoftware.Centron.WPF.UI.Resources"

Usage in XAML:

<!-- For text properties -->
<Label Content="{x:Static properties:LocalizedStrings.LoginDialogView_Benutzername}" />

<!-- For placeholder text -->
<TextEdit NullText="{x:Static properties:LocalizedStrings.LoginDialogView_Benutzername}" />

<!-- For tooltip text -->
<Button ToolTip="{x:Static properties:LocalizedStrings.SomeTooltipKey}" />

Real Example from LoginDialogView.xaml:

<dxe:TextEdit Name="UsernamTextEdit" 
              ShowNullTextForEmptyValue="True"
              NullText="{x:Static properties:LocalizedStrings.LoginDialogView_Benutzername}"
              Text="{Binding Username, UpdateSourceTrigger=PropertyChanged}" />

Code-Behind Usage (WPF UI)

In C# code-behind files in the WPF UI project, add the using statement and access strings directly.

Using Statement:

using CentronSoftware.Centron.WPF.UI.Resources;

Usage in Code:

// For status messages
using (CentronApplication.Instance.AppStatusBar.PushMessage(
           LocalizedStrings.LoginDialogViewModel_DoLogin_Anmeldung))
{
    // Your code here
}

// For exception messages
throw new Exception(LocalizedStrings.SomeErrorMessageKey);

// For dialog messages
var message = LocalizedStrings.ConfirmationMessageKey;

Real Example from LoginDialogViewModel.cs:

using (CentronApplication.Instance.AppStatusBar.PushMessage(
           LocalizedStrings.LoginDialogViewModel_DoLogin_Anmeldung))
{
    var preResult = await PreDoLoginToCentron();
    // ... rest of login logic
}

Business Logic Usage

In business logic classes, localized strings are accessed similarly but using the business logic resource namespace.

Using Statement:

using Centron.BusinessLogic.Resources;

Usage in Business Logic:

// For exception messages
throw new ResultException(
    LocalizedStrings.AppSettingsGroupBL_UpdateUpdateAvailableNotificationSettings_WählenSieMitarbeiterAusDieBeiVerfügbarenUpdatesEineBenachrichtigungAngezeigtBekommenSollen, 
    DefaultMessageCodes.BadRequest);

// For validation messages
var errorMessage = LocalizedStrings.ValidationErrorKey;

Real Example from AppSettingsGroupBL.cs:

throw new ResultException(
    LocalizedStrings.AppSettingsGroupBL_UpdateUpdateAvailableNotificationSettings_WählenSieMitarbeiterAusDieBeiVerfügbarenUpdatesEineBenachrichtigungAngezeigtBekommenSollen, 
    DefaultMessageCodes.BadRequest);

Common WPF Properties Requiring Localization

When auditing XAML files for hardcoded text that needs localization, pay special attention to these classic WPF properties that commonly contain user-facing text:

Primary Text Properties

  • Text - Direct text content (TextBlock, Run, etc.)
  • Content - Button content, CheckBox content, etc.
  • Label - LayoutItem labels, form field labels
  • Header - Headers in controls like TabItem, TreeViewItem, GridColumn headers
  • Title - Window titles, ToolTip titles
  • Caption - Ribbon page captions, group captions

Input Control Properties

  • NullText - Placeholder text in DevExpress editors
  • Watermark - Placeholder text in standard controls
  • ToolTip - Tooltip text for controls and images in DataTemplates

Converter and Template Values

  • Converter Target Values - Hardcoded strings in ObjectToObjectConverter mappings
  • DataTemplate Content - Text within data templates, including ToolTip properties on images and controls
  • Style Setter Values - Hardcoded text in style setters

Grid Controls and Data Tables

  • Header - GridColumn header text that displays column titles
  • Runtime Localization Strings - Grid control runtime strings like "NoRecords" messages
  • DataTemplate ToolTips - Tooltip text on images, buttons, and other controls within cell templates
  • Custom Grid Messages - Any hardcoded text in grid customization areas

Example Search Patterns

When auditing XAML files, search for these patterns:

Title="German Text"
Content="German Text" 
Label="German Text"
Text="German Text"
Caption="German Text"
Header="German Text"
NullText="German Text"
Target="German Text"
ToolTip="German Text"
Value="German Text"

Grid-Specific Examples

Pay special attention to grid controls:

<!-- GridColumn headers -->
<dxg:GridColumn Header="Bezeichnung" />
<dxg:GridColumn Header="Standard" />

<!-- DataTemplate tooltips -->
<Image ToolTip="Änderungen vorhanden" />

<!-- Runtime localization strings -->
<dxg:RuntimeStringIdInfo Value="Keine Verbindungen vorhanden." />

Key Naming Conventions

Localization keys follow a structured naming pattern to ensure uniqueness and maintainability:

  • Format: [ClassName]_[MethodName]_[Description] or [ViewName]_[PropertyName]_[Description]
  • Examples:
    • LoginDialogView_Benutzername - Username field in LoginDialogView
    • LoginDialogViewModel_DoLogin_Anmeldung - Login process message
    • AppSettingsGroupBL_UpdateUpdateAvailableNotificationSettings_WählenSieMitarbeiterAusDieBeiVerfügbarenUpdatesEineBenachrichtigungAngezeigtBekommenSollen - Business logic validation message

Tools

ResXManager

Great tool for managing the language resource files. It is a visual studio extension. It provides a dialog too manage the resource and translate the resources. It also adds a right click menu item "Move to Resource" for quick resource entry creation.

Working

If we encounter strings which are localized through the old workflow (CentronLocalization.Instance.GetLocalizedString()) we replace it with the new workflow.

Translate strings in code

  1. Click into the string. (Complete string selection is not nessassry. The VS-Extension extends the selection automaticly. Be careful if your string contains ". In this case check if the complete text got selected. If not, select manualy.)
  2. Right Click.
  3. Select "Move to Resource".
  4. The popup "Move to Resource" appears.
    • For better read ability select at "Code" the format which adds the class and method name too the generated code.
    • If the string contains variables {0}, {1} add a "Comment" for them. So we have a info in the resource file what values can be expected in the variables.
    • After a klick on "OK" the extension creates a new entry in the resource file and replaces the string with the generated code property.

Namespaces

.xaml: xmlns:properties="clr-namespace:CentronSoftware.Centron.WPF.UI.Resources"
.cs: using CentronSoftware.Centron.WPF.UI.Resources;

Useful searches

These can be used by using the inbuilt search function: Open 'Find and Replace', disable 'Match case' and 'Match whole word', enable 'Use regular expressions' then select 'Currrent document' and 'Entire document'. Now you can just go through the file using 'Find Next' and you should catch most strings.

.cs:
"[^"]*?" - finds all strings
(?=(^((?!///).)*$)).*((".+?")|('.+?')).* - finds all strings excluding comments
(LocalizationManager|CentronLocalization)\.Instance\.GetLocalizedString\("[0-9]*", "[^"]*?"\); - finds texts already translated by the old system

.xaml:
(Text|Label|Caption|ToolTip|Content|Header)="[^{]*?" - finds most common string literals
{lex:Loc[^"]*?" - finds texts already translated by the old system

Keybindings

  1. Open Tools>Options>Keyboard
  2. Search for EditorContextMenus.CodeWindow.Movetoresource
  3. Bind to the keys you like (don't foregt to press Assign)
  4. Profit

Translate entries in the resource file

  1. To translate a resource entry, navigate to the Resource directory in your assembly.
  2. Locate the file "LocalizedStrings.resx".
  3. Right-Click it and select "Open in ResX Manager".

If the Resource Manager shows no files, click on "Refresh view".

  • The manager highlights the not translated entries with a red background color.
  • Additionaly this Tool contains a own tab for the translation. It shows the entries which are not translated. There is a auto translate function too.

Setup localization for a assembly

  1. Create a "Resources" directory, if not existing.
  2. Add "New Item"
  3. Select "Resources File"
  4. Use as Name: LocalizedStrings.resx
  5. Press "Add"-Button
  6. If visual studio does open the resource file automaticly, close it.
  7. Select the new file in the Solution Explorer.
  8. Check The properties.
    • Build Action: Embedded resource
    • Custom Tool: ResXFileCodeGenerator. Enter PublicResXFileCodeGenerator if the assembly contains XAML UI.
  9. Open "ResX Manager" through Tools (Visual Studio menu)
  10. Click on "Refresh View", the new resource file should be visibly now.
  11. Close the manager.
  12. Translate a string in the source code.
  13. Open the ResX Manager again.
  14. If not selected, select the new resource file.
  15. Because we have no resource files for the other languages yet, double click into the edit box and add a translation for the language. The tool will create a new resource file for the language.
  16. Done. We can close the manager.

Its possible that the Resource Manager does not show the new created langugage files from the start. In this case press Refresh. This should fix the issue.

Get localized strings through Web-Service call

To get the message in a specific langugage, it is necessary too add a new Attribut too the header "Accept-Language" (Value example: de-DE).

Example: httpRequest.Headers.Add("Accept-Language", CultureInfo.CurrentUICulture.Name);