Files
2026-04-17 14:55:32 -04:00

6.5 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ViewerSettings/Resources/TranslateExtension.cs
DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ViewerSettings/Resources/StringResources.Designer.cs
2026-04-16T11:12:19.064013+00:00 zai-org/GLM-5-FP8 1 b58f3ee343f377b9

Documentation: DTS.Viewer.ViewerSettings.Resources

1. Purpose

This module provides localization infrastructure for the DTS Viewer settings UI. It consists of two components: TranslateExtension, a WPF MarkupExtension that enables XAML bindings to localized strings, and StringResources, an auto-generated strongly-typed resource class that wraps a .resx file containing the actual localized string values. Together, they allow XAML markup to reference localized strings declaratively (e.g., {local:Translate SomeKey}) while centralizing string management through the .NET resource system.


2. Public Interface

TranslateExtension (public class)

Namespace: DTS.Viewer.ViewerSettings
Base Class: System.Windows.Markup.MarkupExtension
Attribute: [MarkupExtensionReturnType(typeof(string))]

Member Signature Description
Constructor TranslateExtension(string key) Initializes the extension with the resource key to look up. Stores the key in a readonly field _key.
ProvideValue public override object ProvideValue(IServiceProvider serviceProvider) Returns the localized string for _key from StringResources.ResourceManager. Returns NotFound constant if _key is null or empty. Returns NotFound + " " + _key if the key is not found in resources.

Constants:

  • private const string NotFound = "#stringnotfound#" — Fallback value returned when translation cannot be resolved.

StringResources (internal class)

Namespace: DTS.Viewer.ViewerSettings.Resources
Attributes: [GeneratedCode], [DebuggerNonUserCode], [CompilerGenerated]

Member Signature Description
ResourceManager internal static global::System.Resources.ResourceManager ResourceManager { get; } Lazily-initialized, cached ResourceManager instance for the DTS.Viewer.ViewerSettings.Resources.StringResources resource bundle.
Culture internal static global::System.Globalization.CultureInfo Culture { get; set; } Overrides the current thread's CurrentUICulture for resource lookups via this class. Can be set to change localization at runtime.
CalibrationBehavior_LinearIfAvailable internal static string CalibrationBehavior_LinearIfAvailable { get; } Localized string: "Use the linear sensitivity, if available."
CalibrationBehavior_NonLinearIfAvailable internal static string CalibrationBehavior_NonLinearIfAvailable { get; } Localized string: "Use the non-linear sensitivity, if available."
CalibrationBehavior_UseBothIfAvailable internal static string CalibrationBehavior_UseBothIfAvailable { get; } Localized string: "Use both sensitivities, if available, as separate channels."
CalibrationBehaviorText internal static string CalibrationBehaviorText { get; } Localized string: "Calibration Behavior".

3. Invariants

  1. Key immutability: _key in TranslateExtension is assigned once in the constructor and is readonly; it cannot be changed after instantiation.

  2. Non-null return guarantee: TranslateExtension.ProvideValue always returns a non-null string — either the localized value, the NotFound constant, or NotFound + " " + _key.

  3. ResourceManager singleton pattern: StringResources.ResourceManager is lazily initialized on first access and cached; subsequent accesses return the same instance.

  4. Thread-safety of ResourceManager initialization: The getter checks for null using object.ReferenceEquals(resourceMan, null) before creating a new ResourceManager. Note: This pattern is not thread-safe; race conditions could result in multiple ResourceManager instances being created.

  5. Resource key existence: StringResources property getters pass resourceCulture (which may be null) to ResourceManager.GetString, defaulting to the current thread's CurrentUICulture when null.


4. Dependencies

This module depends on:

  • System — Core .NET types
  • System.Windows.MarkupMarkupExtension base class and MarkupExtensionReturnTypeAttribute
  • System.ResourcesResourceManager for resource lookup
  • System.GlobalizationCultureInfo for localization
  • System.CodeDom.Compiler, System.Diagnostics, System.Runtime.CompilerServices — Attributes for generated code (auto-generated dependency)
  • External resource file: StringResources.resx (implied by the designer file; not included in source but required at runtime)

What depends on this module:

  • Cannot be determined from source alone. The TranslateExtension is designed for XAML consumption within the DTS.Viewer.ViewerSettings namespace, but no consumers are shown in the provided files.

5. Gotchas

  1. Different error formats for different failure modes: A null/empty key returns "#stringnotfound#" alone, while a valid but missing key returns "#stringnotfound# {key}". This distinction can be used for debugging but may cause inconsistent UI display if not handled upstream.

  2. StringResources is internal: The class is marked internal, so it cannot be accessed outside the DTS.Viewer.ViewerSettings.Resources namespace's assembly. TranslateExtension works around this by accessing StringResources.ResourceManager directly.

  3. Auto-generated file warning: StringResources.Designer.cs is tool-generated. Manual edits will be lost when the .resx file is modified and the designer regenerates. The actual string values live in StringResources.resx, which is not included in the provided source.

  4. Thread-safety concern: The ResourceManager property getter uses a non-atomic null check pattern that is not thread-safe. In multi-threaded scenarios, two threads could simultaneously pass the null check and create separate ResourceManager instances. While likely harmless in practice (the ResourceManager itself is thread-safe), this violates the singleton intent.

  5. Culture must be set explicitly on StringResources: Setting Thread.CurrentUICulture will NOT affect StringResources lookups if StringResources.Culture has been explicitly set to a non-null value. Consumers must either leave StringResources.Culture as null (to inherit thread culture) or set it explicitly.