| | 1 | | using System; |
| | 2 | | using System.ComponentModel; |
| | 3 | | using System.Diagnostics; |
| | 4 | | using System.Globalization; |
| | 5 | |
|
| | 6 | | namespace PropertyGridHelpers.Attributes |
| | 7 | | { |
| | 8 | | #if NET8_0_OR_GREATER |
| | 9 | | /// <summary> |
| | 10 | | /// Provides a base attribute class for attaching localized display text |
| | 11 | | /// to properties or fields using a resource key. |
| | 12 | | /// </summary> |
| | 13 | | /// <param name="resourceKey"> |
| | 14 | | /// The key used to look up the localized string in the resource file. |
| | 15 | | /// </param> |
| | 16 | | /// <seealso cref="Attribute" /> |
| 140 | 17 | | public abstract class LocalizedTextAttribute(string resourceKey) : Attribute |
| | 18 | | #else |
| | 19 | | /// <summary> |
| | 20 | | /// Provides a base attribute class for attaching localized display text |
| | 21 | | /// to properties or fields using a resource key. |
| | 22 | | /// </summary> |
| | 23 | | /// <seealso cref="Attribute" /> |
| | 24 | | public abstract class LocalizedTextAttribute : Attribute |
| | 25 | | #endif |
| | 26 | | { |
| | 27 | | /// <summary> |
| | 28 | | /// Gets the resource key associated with this attribute. |
| | 29 | | /// </summary> |
| | 30 | | /// <value> |
| | 31 | | /// The resource key to look up in a resource file. |
| | 32 | | /// </value> |
| | 33 | | public string ResourceKey |
| | 34 | | { |
| 128 | 35 | | get; |
| | 36 | | #if NET8_0_OR_GREATER |
| 140 | 37 | | } = resourceKey; |
| | 38 | | #else |
| | 39 | | } |
| | 40 | |
|
| | 41 | | /// <summary> |
| | 42 | | /// Initializes a new instance of the <see cref="LocalizedTextAttribute"/> class. |
| | 43 | | /// </summary> |
| | 44 | | /// <param name="resourceKey"> |
| | 45 | | /// The key used to look up the localized string in the resource file. |
| | 46 | | /// </param> |
| 16 | 47 | | protected LocalizedTextAttribute(string resourceKey) => |
| 16 | 48 | | ResourceKey = resourceKey; |
| | 49 | | #endif |
| | 50 | |
|
| | 51 | | /// <summary> |
| | 52 | | /// Resolves and retrieves the localized text for this attribute using |
| | 53 | | /// the provided target type's associated <see cref="ResourcePathAttribute" />. |
| | 54 | | /// </summary> |
| | 55 | | /// <param name="context">The context.</param> |
| | 56 | | /// <param name="culture">The culture.</param> |
| | 57 | | /// <param name="targetType">The type whose resource path is used to locate the resource class.</param> |
| | 58 | | /// <returns> |
| | 59 | | /// The resolved localized string based on the <see cref="ResourceKey" /> and the |
| | 60 | | /// target type's resource path. |
| | 61 | | /// </returns> |
| | 62 | | /// <exception cref="System.InvalidOperationException"> |
| | 63 | | /// ResourcePathAttribute not found on {targetType.FullName} |
| | 64 | | /// or |
| | 65 | | /// Resource type '{fullResourcePath}' not found in assembly '{rootNamespace}' |
| | 66 | | /// </exception> |
| | 67 | | /// <exception cref="InvalidOperationException">Thrown if the <see cref="ResourcePathAttribute" /> is missing or |
| | 68 | | /// resource type cannot be located in the assembly.</exception> |
| | 69 | | public string GetLocalizedText(ITypeDescriptorContext context, CultureInfo culture, Type targetType) |
| 52 | 70 | | { |
| | 71 | | // Retrieve the ResourcePathAttribute from the target type |
| 60 | 72 | | var resourcePath = Support.Support.GetResourcePath(context, targetType, Enums.ResourceUsage.Strings); |
| | 73 | |
|
| 52 | 74 | | Debug.WriteLine($"ResourcePath: {resourcePath}"); |
| | 75 | |
|
| | 76 | | // Get the namespace of the target type itself |
| | 77 | | // Extract the root namespace (first segment of the namespace) |
| 60 | 78 | | var rootNamespace = targetType.Namespace.Split('.')[0]; |
| | 79 | |
|
| | 80 | | // Combine the assembly namespace with the resource path |
| 60 | 81 | | var fullResourcePath = $"{rootNamespace}.{resourcePath}"; |
| 60 | 82 | | Console.WriteLine($"Computed ResourcePath: {fullResourcePath}"); |
| | 83 | |
|
| | 84 | | // Determine the resource source type dynamically |
| 60 | 85 | | var resourceSource = targetType.Assembly.GetType(fullResourcePath) // Convert path to a Type |
| 60 | 86 | | ?? throw new InvalidOperationException($"Resource type '{fullResourcePath}' not found in assembly '{roo |
| | 87 | |
|
| | 88 | | // Call your existing method to get the localized string |
| 56 | 89 | | return Support.Support.GetResourceString(ResourceKey, culture, resourceSource); |
| 48 | 90 | | } |
| | 91 | |
|
| | 92 | | /// <summary> |
| | 93 | | /// Retrieves the <see cref="LocalizedTextAttribute"/> from the given |
| | 94 | | /// type descriptor context, if available. |
| | 95 | | /// </summary> |
| | 96 | | /// <param name="context"> |
| | 97 | | /// The design-time or runtime type descriptor context. |
| | 98 | | /// </param> |
| | 99 | | /// <returns> |
| | 100 | | /// The <see cref="LocalizedTextAttribute"/> if found, or <c>null</c> if not present. |
| | 101 | | /// </returns> |
| | 102 | | public static LocalizedTextAttribute Get(ITypeDescriptorContext context) => |
| 28 | 103 | | context == null || context.Instance == null || context.PropertyDescriptor == null |
| 28 | 104 | | ? null |
| 28 | 105 | | : Support.Support.GetFirstCustomAttribute<LocalizedTextAttribute>( |
| 28 | 106 | | Support.Support.GetPropertyInfo(context)); |
| | 107 | | } |
| | 108 | | } |