Skip to content

Commit 941cc4e

Browse files
committed
fix: relayCommand when canExecute is a property
1 parent cebc319 commit 941cc4e

File tree

2 files changed

+98
-3
lines changed

2 files changed

+98
-3
lines changed

src/Atc.Wpf.SourceGenerators/Extensions/ViewModelBuilderExtensions.cs

+20-3
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ private static void GenerateRelayCommandWithOutParameterValues(
8282
implementationType,
8383
rc.CommandName,
8484
rc.MethodName,
85-
rc.CanExecuteName);
85+
rc.CanExecuteName,
86+
rc.UsePropertyForCanExecute);
8687
builder.AppendLine(cmd);
8788
}
8889
else if (rc.ParameterTypes.Length == 1)
@@ -108,7 +109,8 @@ private static void GenerateRelayCommandWithOutParameterValues(
108109
$"{implementationType}{generic}",
109110
rc.CommandName,
110111
rc.MethodName,
111-
rc.CanExecuteName);
112+
rc.CanExecuteName,
113+
rc.UsePropertyForCanExecute);
112114
builder.AppendLine(cmd);
113115
}
114116
}
@@ -229,14 +231,29 @@ private static string GenerateCommandLine(
229231
string commandName,
230232
string constructorParameters,
231233
string? canExecuteName = null,
234+
bool usePropertyForCanExecute = false,
232235
bool isLambda = false)
233236
{
234237
var lambdaPrefix = isLambda ? "() => " : string.Empty;
235238
var commandInstance = $"new {implementationType}({lambdaPrefix}{constructorParameters}";
236239

237240
if (canExecuteName is not null)
238241
{
239-
commandInstance += $", {canExecuteName}";
242+
if (usePropertyForCanExecute)
243+
{
244+
if (interfaceType.Contains('<'))
245+
{
246+
commandInstance += $", _ => {canExecuteName}";
247+
}
248+
else
249+
{
250+
commandInstance += $", () => {canExecuteName}";
251+
}
252+
}
253+
else
254+
{
255+
commandInstance += $", {canExecuteName}";
256+
}
240257
}
241258

242259
commandInstance += ");";

test/Atc.Wpf.SourceGenerators.Tests/Generators/ViewModelGeneratorTests.cs

+78
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,84 @@ public partial class TestViewModel
10041004
AssertGeneratorRunResultAsEqual(expectedCode, generatorResult);
10051005
}
10061006

1007+
[Fact]
1008+
public void RelayCommand_NoParameter_CanExecuteOnProperty()
1009+
{
1010+
const string inputCode =
1011+
"""
1012+
namespace TestNamespace;
1013+
1014+
public partial class TestViewModel : ViewModelBase
1015+
{
1016+
[RelayCommand(CanExecute = nameof(CanSave))]
1017+
public void Save()
1018+
{
1019+
}
1020+
1021+
public bool CanSave => return true;
1022+
}
1023+
""";
1024+
1025+
const string expectedCode =
1026+
"""
1027+
// <auto-generated>
1028+
#nullable enable
1029+
using Atc.Wpf.Command;
1030+
1031+
namespace TestNamespace;
1032+
1033+
public partial class TestViewModel
1034+
{
1035+
public IRelayCommand SaveCommand => new RelayCommand(Save, () => CanSave);
1036+
}
1037+
1038+
#nullable disable
1039+
""";
1040+
1041+
var generatorResult = RunGenerator<ViewModelGenerator>(inputCode);
1042+
1043+
AssertGeneratorRunResultAsEqual(expectedCode, generatorResult);
1044+
}
1045+
1046+
[Fact]
1047+
public void RelayCommand_ParameterString_CanExecuteOnProperty()
1048+
{
1049+
const string inputCode =
1050+
"""
1051+
namespace TestNamespace;
1052+
1053+
public partial class TestViewModel : ViewModelBase
1054+
{
1055+
[RelayCommand(CanExecute = nameof(CanSave))]
1056+
public void Save(string val)
1057+
{
1058+
}
1059+
1060+
public bool CanSave => return true;
1061+
}
1062+
""";
1063+
1064+
const string expectedCode =
1065+
"""
1066+
// <auto-generated>
1067+
#nullable enable
1068+
using Atc.Wpf.Command;
1069+
1070+
namespace TestNamespace;
1071+
1072+
public partial class TestViewModel
1073+
{
1074+
public IRelayCommand<string> SaveCommand => new RelayCommand<string>(Save, _ => CanSave);
1075+
}
1076+
1077+
#nullable disable
1078+
""";
1079+
1080+
var generatorResult = RunGenerator<ViewModelGenerator>(inputCode);
1081+
1082+
AssertGeneratorRunResultAsEqual(expectedCode, generatorResult);
1083+
}
1084+
10071085
[Fact]
10081086
public void AsyncRelayCommand_NoParameter()
10091087
{

0 commit comments

Comments
 (0)