Skip to content

Commit 10402b3

Browse files
authored
Ensure Category attribute works well when UseSystemResourceKeys feature is turned on (#57227)
* Ensure Category attribute works well when UseSystemResourceKeys feature is turned on * PR feedback and fix unit test failures
1 parent 022172a commit 10402b3

File tree

4 files changed

+99
-1
lines changed

4 files changed

+99
-1
lines changed

src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFrameworks>$(NetCoreAppCurrent)</TargetFrameworks>
4+
<!--
5+
Since many resource strings in this library are shown to an end-user,
6+
always generate default resource string values which will be used when UseSystemResourceKeys is true in trimmed apps.
7+
-->
8+
<GenerateResxSourceIncludeDefaultValues>true</GenerateResxSourceIncludeDefaultValues>
49
<Nullable>enable</Nullable>
510
</PropertyGroup>
611
<ItemGroup>

src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/CategoryAttribute.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,31 @@ public override bool Equals([NotNullWhen(true)] object? obj) =>
199199
/// <summary>
200200
/// Looks up the localized name of a given category.
201201
/// </summary>
202-
protected virtual string? GetLocalizedString(string value) => SR.GetResourceString("PropertyCategory" + value);
202+
protected virtual string? GetLocalizedString(string value) => value switch
203+
{
204+
"Action" => SR.PropertyCategoryAction,
205+
"Appearance" => SR.PropertyCategoryAppearance,
206+
"Asynchronous" => SR.PropertyCategoryAsynchronous,
207+
"Behavior" => SR.PropertyCategoryBehavior,
208+
"Config" => SR.PropertyCategoryConfig,
209+
"Data" => SR.PropertyCategoryData,
210+
"DDE" => SR.PropertyCategoryDDE,
211+
"Default" => SR.PropertyCategoryDefault,
212+
"Design" => SR.PropertyCategoryDesign,
213+
"DragDrop" => SR.PropertyCategoryDragDrop,
214+
"Focus" => SR.PropertyCategoryFocus,
215+
"Font" => SR.PropertyCategoryFont,
216+
"Format" => SR.PropertyCategoryFormat,
217+
"Key" => SR.PropertyCategoryKey,
218+
"Layout" => SR.PropertyCategoryLayout,
219+
"List" => SR.PropertyCategoryList,
220+
"Mouse" => SR.PropertyCategoryMouse,
221+
"Position" => SR.PropertyCategoryPosition,
222+
"Scale" => SR.PropertyCategoryScale,
223+
"Text" => SR.PropertyCategoryText,
224+
"WindowStyle" => SR.PropertyCategoryWindowStyle,
225+
_ => null
226+
};
203227

204228
public override bool IsDefaultAttribute() => Category == Default.Category;
205229
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project DefaultTargets="Build">
2+
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.props))" />
3+
4+
<ItemGroup>
5+
<TestConsoleAppSourceFiles Include="VerifyCategoryNamesDontGetTrimmed.cs">
6+
<!-- Setting the Trimming feature switch to make sure that the Resources get trimmed by the linker
7+
as this test will ensure Category names will use default values when the switch is on. -->
8+
<EnabledFeatureSwitches>System.Resources.UseSystemResourceKeys</EnabledFeatureSwitches>
9+
</TestConsoleAppSourceFiles>
10+
</ItemGroup>
11+
12+
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.targets))" />
13+
</Project>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.ComponentModel;
6+
7+
namespace Test
8+
{
9+
/// <summary>
10+
/// When UseSystemResourceStrings feature switch is on, we want to validate that getting the resource string of
11+
/// a category attribute won't result in having "PropertyCategory" appended to the beginning of the resulting string.
12+
/// This test ensures that both built-in categories as well as custom categories get the right Category when the
13+
/// feature switch is on.
14+
/// </summary>
15+
public class Program
16+
{
17+
public static int Main()
18+
{
19+
if (GetEnumCategory(AnEnum.Action) == "Action" && GetEnumCategory(AnEnum.Something) == "Something" && GetEnumCategory(AnEnum.WindowStyle) == "Window Style")
20+
{
21+
return 100;
22+
}
23+
return -1;
24+
}
25+
26+
public static string GetEnumCategory<T>(T enumValue)
27+
where T : struct, IConvertible
28+
{
29+
if (!typeof(T).IsEnum)
30+
return null;
31+
var enumCategory = enumValue.ToString();
32+
var fieldInfo = enumValue.GetType().GetField(enumValue.ToString());
33+
if (fieldInfo != null)
34+
{
35+
var attrs = fieldInfo.GetCustomAttributes(typeof(CategoryAttribute), false);
36+
if (attrs != null && attrs.Length > 0)
37+
{
38+
enumCategory = ((CategoryAttribute)attrs[0]).Category;
39+
}
40+
}
41+
return enumCategory;
42+
}
43+
}
44+
45+
public enum AnEnum
46+
{
47+
[Category("Action")] // Built-in category
48+
Action = 1,
49+
50+
[Category("Something")] // Custom category
51+
Something = 2,
52+
53+
[Category("WindowStyle")] // Built-in category with localized string different than category name.
54+
WindowStyle = 3,
55+
}
56+
}

0 commit comments

Comments
 (0)