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

280 lines
11 KiB
Markdown

# 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:
```xml
xmlns:properties="clr-namespace:CentronSoftware.Centron.WPF.UI.Resources"
```
**Usage in XAML:**
```xml
<!-- 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:**
```xml
<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:**
```csharp
using CentronSoftware.Centron.WPF.UI.Resources;
```
**Usage in Code:**
```csharp
// 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:**
```csharp
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:**
```csharp
using Centron.BusinessLogic.Resources;
```
**Usage in Business Logic:**
```csharp
// 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:**
```csharp
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:
```xml
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:
```xml
<!-- 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);