diff --git a/src/ReactiveUI.WPF.SampleApp/ViewModels/QuestionnaireViewModel.cs b/src/ReactiveUI.WPF.SampleApp/ViewModels/QuestionnaireViewModel.cs index c4249523..3c3684c1 100644 --- a/src/ReactiveUI.WPF.SampleApp/ViewModels/QuestionnaireViewModel.cs +++ b/src/ReactiveUI.WPF.SampleApp/ViewModels/QuestionnaireViewModel.cs @@ -71,7 +71,7 @@ public QuestionnaireViewModel() vm => vm.AnswerFive, vm => vm.AnswerFiveLengthRemaining); - LaunchInteraction = ReactiveCommand.CreateFromTask(() => OnLaunchInteraction()); + LaunchInteraction = ReactiveCommand.CreateFromTask(OnLaunchInteraction); } /// diff --git a/src/ReactiveUI.WPF.SampleApp/Views/QuestionnaireView.xaml.cs b/src/ReactiveUI.WPF.SampleApp/Views/QuestionnaireView.xaml.cs index 0650aecf..81dfe8c5 100644 --- a/src/ReactiveUI.WPF.SampleApp/Views/QuestionnaireView.xaml.cs +++ b/src/ReactiveUI.WPF.SampleApp/Views/QuestionnaireView.xaml.cs @@ -25,6 +25,9 @@ public QuestionnaireView() private void OnWhenActivated(Action disposeWithAction) { +#if TBC + disposeWithAction(this.BindCommand(ViewModel, vw => vw.LaunchInteraction, vm => vm.LaunchInteraction)); +#endif new QuestionnaireViewBindingModels().ApplyBindings( disposeWithAction, this, diff --git a/src/Vetuviem.Core/CommandBinding.cs b/src/Vetuviem.Core/CommandBinding.cs index e3c2d9dd..76ab45a3 100644 --- a/src/Vetuviem.Core/CommandBinding.cs +++ b/src/Vetuviem.Core/CommandBinding.cs @@ -4,7 +4,6 @@ using System; using System.Linq.Expressions; -using System.Reactive; using System.Reactive.Disposables; using System.Windows.Input; using ReactiveUI; @@ -15,72 +14,19 @@ namespace Vetuviem.Core /// Represents a command binding between a control and a viewmodel. /// /// The type for the viewmodel. - public class CommandBinding : CommandBinding + public class CommandBinding : ICommandBinding where TViewModel : class { - /// - /// Initializes a new instance of the class. - /// - /// Expression for the View Model binding. - /// If specified, bind to the specific event instead of the default. - public CommandBinding( - Expression?>> viewModelBinding, - string? toEvent = null) - : base( - viewModelBinding, - toEvent) - { - } - } - - /// - /// Represents a command binding between a control and a viewmodel. - /// - /// The type for the viewmodel. - /// - /// The type of the values that are the result of command execution. - /// - public class CommandBinding : CommandBinding - where TViewModel : class - { - /// - /// Initializes a new instance of the class. - /// - /// Expression for the View Model binding. - /// If specified, bind to the specific event instead of the default. - public CommandBinding( - Expression?>> viewModelBinding, - string? toEvent = null) - : base( - viewModelBinding, - toEvent) - { - } - } - - /// - /// Represents a command binding between a control and a viewmodel. - /// - /// The type for the viewmodel. - /// - /// The type of parameter values passed in during command execution. - /// - /// - /// The type of the values that are the result of command execution. - /// - public class CommandBinding : ICommandBinding - where TViewModel : class - { - private readonly Expression?>> _viewModelBinding; + private readonly Expression> _viewModelBinding; private readonly string? _toEvent; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Expression for the View Model binding. /// If specified, bind to the specific event instead of the default. public CommandBinding( - Expression?>> viewModelBinding, + Expression> viewModelBinding, string? toEvent = null) { _viewModelBinding = viewModelBinding; diff --git a/src/Vetuviem.SourceGenerator/Features/ControlBindingModels/ControlBindingModelPropertyGenerator.cs b/src/Vetuviem.SourceGenerator/Features/ControlBindingModels/ControlBindingModelPropertyGenerator.cs index 15bd8247..40fc6576 100644 --- a/src/Vetuviem.SourceGenerator/Features/ControlBindingModels/ControlBindingModelPropertyGenerator.cs +++ b/src/Vetuviem.SourceGenerator/Features/ControlBindingModels/ControlBindingModelPropertyGenerator.cs @@ -156,6 +156,8 @@ private static TypeSyntax GetBindingTypeSyntax( prop, desiredCommandInterface); +#error we need to change command to handle the control type instead of the property type. This is because BindCommand binds to the control, not the property. + var returnType = prop.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); var type = SyntaxFactory.ParseTypeName($"global::Vetuviem.Core.{bindingName}?"); return type; diff --git a/src/Vetuviem.SourceGenerator/Features/ControlBindingModels/GenericControlBindingModelClassGenerator.cs b/src/Vetuviem.SourceGenerator/Features/ControlBindingModels/GenericControlBindingModelClassGenerator.cs index 89d21671..b7f35d35 100644 --- a/src/Vetuviem.SourceGenerator/Features/ControlBindingModels/GenericControlBindingModelClassGenerator.cs +++ b/src/Vetuviem.SourceGenerator/Features/ControlBindingModels/GenericControlBindingModelClassGenerator.cs @@ -388,14 +388,23 @@ private static StatementSyntax[] GetApplyBindingMethodBody( continue; } - var propType = propertySymbol.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); + var propType = propertySymbol.Type; + var propTypeDisplayString = propType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); + + var isCommand = !string.IsNullOrWhiteSpace(desiredCommandInterface) && + (propType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).Equals(desiredCommandInterface, StringComparison.Ordinal) + || propType.AllInterfaces.Any(interfaceName => interfaceName.GetFullName().Equals(desiredCommandInterface, StringComparison.Ordinal))); + + var expressionArg = isCommand + ? propertySymbol.Name + : $"global::Vetuviem.Core.ExpressionHelpers.GetControlPropertyExpressionFromViewExpression(VetuviemControlBindingExpression, \"{propertySymbol.Name}\")"; var invokeArgs = new[] { "registerForDisposalAction", "view", "viewModel", - $"global::Vetuviem.Core.ExpressionHelpers.GetControlPropertyExpressionFromViewExpression(VetuviemControlBindingExpression, \"{propertySymbol.Name}\")", + expressionArg, }; var invocationStatement = RoslynGenerationHelpers.GetMethodOnPropertyOfVariableInvocationSyntax( @@ -406,7 +415,7 @@ private static StatementSyntax[] GetApplyBindingMethodBody( AddInvocationStatementToRelevantCollection( propertySymbol, - desiredCommandInterface, + isCommand, invocationStatement, commandBindingStatements, oneWayBindingStatements, @@ -471,14 +480,23 @@ private static StatementSyntax[] GetApplyBindingCompositeDisposableMethodBody(IN continue; } - var propType = propertySymbol.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); + var propType = propertySymbol.Type; + var propTypeDisplayString = propType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); + + var isCommand = !string.IsNullOrWhiteSpace(desiredCommandInterface) && + (propType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).Equals(desiredCommandInterface, StringComparison.Ordinal) + || propType.AllInterfaces.Any(interfaceName => interfaceName.GetFullName().Equals(desiredCommandInterface, StringComparison.Ordinal))); + + var expressionArg = isCommand + ? propertySymbol.Name + : $"global::Vetuviem.Core.ExpressionHelpers.GetControlPropertyExpressionFromViewExpression(VetuviemControlBindingExpression, \"{propertySymbol.Name}\")"; var invokeArgs = new[] { "compositeDisposable", "view", "viewModel", - $"global::Vetuviem.Core.ExpressionHelpers.GetControlPropertyExpressionFromViewExpression(VetuviemControlBindingExpression, \"{propertySymbol.Name}\")", + expressionArg, }; var invocationStatement = RoslynGenerationHelpers.GetMethodOnPropertyOfVariableInvocationSyntax( @@ -489,7 +507,7 @@ private static StatementSyntax[] GetApplyBindingCompositeDisposableMethodBody(IN AddInvocationStatementToRelevantCollection( propertySymbol, - desiredCommandInterface, + isCommand, invocationStatement, commandBindingStatements, oneWayBindingStatements, @@ -505,22 +523,16 @@ private static StatementSyntax[] GetApplyBindingCompositeDisposableMethodBody(IN private static void AddInvocationStatementToRelevantCollection( IPropertySymbol prop, - string? desiredCommandInterface, + bool isCommand, StatementSyntax invocation, ICollection commandBindingStatements, ICollection oneWayBindingStatements, ICollection twoWayBindingStatements) { - if (!string.IsNullOrWhiteSpace(desiredCommandInterface)) + if (isCommand) { - var propType = prop.Type; - var isCommand = propType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).Equals(desiredCommandInterface, StringComparison.Ordinal) - || propType.AllInterfaces.Any(interfaceName => interfaceName.GetFullName().Equals(desiredCommandInterface, StringComparison.Ordinal)); - if (isCommand) - { - commandBindingStatements.Add(invocation); - return; - } + commandBindingStatements.Add(invocation); + return; } if (prop.IsReadOnly)