InvokeCommandAction.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. using System.Diagnostics.Tracing;
  2. using System.Windows.Input;
  3. using Avalonia.Data.Converters;
  4. using CommunityToolkit.Mvvm.Input;
  5. namespace Avalonia.Xaml.Interactions.Core;
  6. /// <summary>
  7. /// Executes a specified <see cref="System.Windows.Input.ICommand"/> when invoked.
  8. /// </summary>
  9. public class InvokeCommandAction : Interactivity.Action
  10. {
  11. /// <summary>
  12. /// Identifies the <seealso cref="Command"/> avalonia property.
  13. /// </summary>
  14. public static readonly StyledProperty<ICommand?> CommandProperty =
  15. AvaloniaProperty.Register<InvokeCommandAction, ICommand?>(nameof(Command));
  16. /// <summary>
  17. /// Identifies the <seealso cref="CommandParameter"/> avalonia property.
  18. /// </summary>
  19. public static readonly StyledProperty<object?> CommandParameterProperty =
  20. AvaloniaProperty.Register<InvokeCommandAction, object?>(nameof(CommandParameter));
  21. /// <summary>
  22. /// Identifies the <seealso cref="InputConverter"/> avalonia property.
  23. /// </summary>
  24. public static readonly StyledProperty<IValueConverter?> InputConverterProperty =
  25. AvaloniaProperty.Register<InvokeCommandAction, IValueConverter?>(nameof(InputConverter));
  26. /// <summary>
  27. /// Identifies the <seealso cref="InputConverterParameter"/> avalonia property.
  28. /// </summary>
  29. public static readonly StyledProperty<object?> InputConverterParameterProperty =
  30. AvaloniaProperty.Register<InvokeCommandAction, object?>(nameof(InputConverterParameter));
  31. /// <summary>
  32. /// Identifies the <seealso cref="InputConverterLanguage"/> avalonia property.
  33. /// </summary>
  34. /// <remarks>The string.Empty used for default value string means the invariant culture.</remarks>
  35. public static readonly StyledProperty<string?> InputConverterLanguageProperty =
  36. AvaloniaProperty.Register<InvokeCommandAction, string?>(nameof(InputConverterLanguage), string.Empty);
  37. /// <summary>
  38. /// Gets or sets the command this action should invoke. This is a avalonia property.
  39. /// </summary>
  40. public ICommand? Command
  41. {
  42. get => GetValue(CommandProperty);
  43. set => SetValue(CommandProperty, value);
  44. }
  45. /// <summary>
  46. /// Gets or sets the parameter that is passed to <see cref="System.Windows.Input.ICommand.Execute(object)"/>.
  47. /// If this is not set, the parameter from the <seealso cref="Execute(object, object)"/> method will be used.
  48. /// This is an optional avalonia property.
  49. /// </summary>
  50. public object? CommandParameter
  51. {
  52. get => GetValue(CommandParameterProperty);
  53. set => SetValue(CommandParameterProperty, value);
  54. }
  55. /// <summary>
  56. /// Gets or sets the converter that is run on the parameter from the <seealso cref="Execute(object, object)"/> method.
  57. /// This is an optional avalonia property.
  58. /// </summary>
  59. public IValueConverter? InputConverter
  60. {
  61. get => GetValue(InputConverterProperty);
  62. set => SetValue(InputConverterProperty, value);
  63. }
  64. /// <summary>
  65. /// Gets or sets the parameter that is passed to the <see cref="IValueConverter.Convert"/>
  66. /// method of <see cref="InputConverter"/>.
  67. /// This is an optional avalonia property.
  68. /// </summary>
  69. public object? InputConverterParameter
  70. {
  71. get => GetValue(InputConverterParameterProperty);
  72. set => SetValue(InputConverterParameterProperty, value);
  73. }
  74. /// <summary>
  75. /// Gets or sets the language that is passed to the <see cref="IValueConverter.Convert"/>
  76. /// method of <see cref="InputConverter"/>.
  77. /// This is an optional avalonia property.
  78. /// </summary>
  79. public string? InputConverterLanguage
  80. {
  81. get => GetValue(InputConverterLanguageProperty);
  82. set => SetValue(InputConverterLanguageProperty, value);
  83. }
  84. /// <summary>
  85. /// Specifies whether the EventArgs of the event that triggered this action should be passed to the Command as a parameter.
  86. /// </summary>
  87. public bool PassEventArgsToCommand { get; set; }
  88. /// <summary>
  89. /// Executes the action.
  90. /// </summary>
  91. /// <param name="sender">The <see cref="object"/> that is passed to the action by the behavior. Generally this is <seealso cref="Avalonia.Xaml.Interactivity.IBehavior.AssociatedObject"/> or a target object.</param>
  92. /// <param name="parameter">The value of this parameter is determined by the caller.</param>
  93. /// <returns>True if the command is successfully executed; else false.</returns>
  94. public override object Execute(object? sender, object? parameter)
  95. {
  96. if (IsEnabled != true || Command is null)
  97. {
  98. return false;
  99. }
  100. object? resolvedParameter = default;
  101. if (IsSet(CommandParameterProperty))
  102. {
  103. resolvedParameter = CommandParameter;
  104. }
  105. else if (InputConverter is not null)
  106. {
  107. resolvedParameter = InputConverter.Convert(
  108. parameter,
  109. typeof(object),
  110. InputConverterParameter,
  111. InputConverterLanguage is not null
  112. ?
  113. new System.Globalization.CultureInfo(InputConverterLanguage)
  114. : System.Globalization.CultureInfo.CurrentCulture);
  115. }
  116. else
  117. {
  118. if (PassEventArgsToCommand)
  119. {
  120. resolvedParameter = parameter;
  121. }
  122. }
  123. if (!Command.CanExecute(resolvedParameter))
  124. {
  125. return false;
  126. }
  127. if (Command is IRelayCommand command) command.Execute(sender, resolvedParameter);
  128. else Command.Execute(resolvedParameter);
  129. return true;
  130. }
  131. }