Skip to content

Commit 39290dc

Browse files
authored
Merge pull request #475 from CommunityToolkit/dev/lower-command-names
Fix [RelayCommand] for methods that can't be lowered
2 parents e2140f2 + ec9c1d9 commit 39290dc

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

CommunityToolkit.Mvvm.SourceGenerators/Input/RelayCommandGenerator.Execute.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,17 @@ public static (string FieldName, string PropertyName) GetGeneratedFieldAndProper
439439

440440
propertyName += "Command";
441441

442-
string fieldName = $"{char.ToLower(propertyName[0], CultureInfo.InvariantCulture)}{propertyName.Substring(1)}";
442+
char firstCharacter = propertyName[0];
443+
char loweredFirstCharacter = char.ToLower(firstCharacter, CultureInfo.InvariantCulture);
444+
445+
// The field name is generated depending on whether the first character can be lowered:
446+
// - If it can, then the field name is just the property name starting in lowercase.
447+
// - If it can't (eg. starts with '中'), then the '_' prefix is added to the property name.
448+
string fieldName = (firstCharacter == loweredFirstCharacter) switch
449+
{
450+
true => $"_{propertyName}",
451+
false => $"{loweredFirstCharacter}{propertyName.Substring(1)}"
452+
};
443453

444454
return (fieldName, propertyName);
445455
}

tests/CommunityToolkit.Mvvm.UnitTests/Test_ObservablePropertyAttribute.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,25 @@ public void Test_ObservableProperty_WithExplicitAttributeForProperty()
946946
Assert.AreEqual(testAttribute2.Animal, (Animal)67);
947947
}
948948

949+
// See https://github.com/CommunityToolkit/dotnet/issues/446
950+
[TestMethod]
951+
public void Test_ObservableProperty_CommandNamesThatCantBeLowered()
952+
{
953+
ModelWithCommandNamesThatCantBeLowered model = new();
954+
955+
// Just ensures this builds
956+
_ = model.中文Command;
957+
_ = model.c中文Command;
958+
959+
FieldInfo? fieldInfo = typeof(ModelWithCommandNamesThatCantBeLowered).GetField($"_{nameof(ModelWithCommandNamesThatCantBeLowered.中文)}Command", BindingFlags.Instance | BindingFlags.NonPublic);
960+
961+
Assert.AreSame(model.中文Command, fieldInfo.GetValue(model));
962+
963+
fieldInfo = typeof(ModelWithCommandNamesThatCantBeLowered).GetField($"_{nameof(ModelWithCommandNamesThatCantBeLowered.c中文)}Command", BindingFlags.Instance | BindingFlags.NonPublic);
964+
965+
Assert.AreSame(model.c中文Command, fieldInfo.GetValue(model));
966+
}
967+
949968
public abstract partial class BaseViewModel : ObservableObject
950969
{
951970
public string? Content { get; set; }
@@ -1517,4 +1536,17 @@ public PropertyInfoAttribute(object? o, Type t, bool flag, double d, string[] na
15171536

15181537
public Animal Animal { get; set; }
15191538
}
1539+
1540+
private sealed partial class ModelWithCommandNamesThatCantBeLowered
1541+
{
1542+
[RelayCommand]
1543+
public void 中文()
1544+
{
1545+
}
1546+
1547+
[RelayCommand]
1548+
public void c中文()
1549+
{
1550+
}
1551+
}
15201552
}

0 commit comments

Comments
 (0)