Skip to content

Commit

Permalink
Add action base class
Browse files Browse the repository at this point in the history
  • Loading branch information
wieslawsoltes committed Sep 1, 2024
1 parent 52c2a83 commit ca91842
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 35 deletions.
9 changes: 7 additions & 2 deletions src/Avalonia.Xaml.Interactions.Custom/AddClassAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Avalonia.Xaml.Interactions.Custom;
/// <summary>
/// Adds a specified <see cref="AddClassAction.ClassName"/> to the <see cref="StyledElement.Classes"/> collection when invoked.
/// </summary>
public class AddClassAction : AvaloniaObject, IAction
public class AddClassAction : ActionBase
{
/// <summary>
/// Identifies the <seealso cref="ClassName"/> avalonia property.
Expand Down Expand Up @@ -60,8 +60,13 @@ public bool RemoveIfExists
/// <param name="sender">The <see cref="object"/> that is passed to the action by the behavior. Generally this is <seealso cref="IBehavior.AssociatedObject"/> or a target object.</param>
/// <param name="parameter">The value of this parameter is determined by the caller.</param>
/// <returns>True if the class is successfully added; else false.</returns>
public object Execute(object? sender, object? parameter)
public override object Execute(object? sender, object? parameter)
{
if (!IsEnabled)
{
return false;
}

var target = GetValue(StyledElementProperty) is not null ? StyledElement : sender as StyledElement;
if (target is null || string.IsNullOrEmpty(ClassName))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Avalonia.Xaml.Interactions.Custom;
/// <summary>
/// An action that will change a specified Avalonia property to a specified value when invoked.
/// </summary>
public class ChangeAvaloniaPropertyAction : AvaloniaObject, IAction
public class ChangeAvaloniaPropertyAction : ActionBase
{
/// <summary>
/// Identifies the <seealso cref="TargetProperty"/> avalonia property.
Expand Down Expand Up @@ -65,8 +65,13 @@ public AvaloniaObject? TargetObject
/// <param name="sender">The <see cref="object"/> that is passed to the action by the behavior. Generally this is <seealso cref="IBehavior.AssociatedObject"/> or a target object.</param>
/// <param name="parameter">The value of this parameter is determined by the caller.</param>
/// <returns>True if updating the property value succeeds; else false.</returns>
public virtual object Execute(object? sender, object? parameter)
public override object Execute(object? sender, object? parameter)
{
if (!IsEnabled)
{
return false;
}

var targetObject = GetValue(TargetObjectProperty) is not null ? TargetObject : sender;
if (targetObject is AvaloniaObject avaloniaObject && TargetProperty is not null)
{
Expand Down
9 changes: 7 additions & 2 deletions src/Avalonia.Xaml.Interactions.Custom/FocusControlAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Avalonia.Xaml.Interactions.Custom;
/// <summary>
/// Focuses the associated or target control when executed.
/// </summary>
public class FocusControlAction : AvaloniaObject, IAction
public class FocusControlAction : ActionBase
{
/// <summary>
/// Identifies the <seealso cref="TargetControl"/> avalonia property.
Expand All @@ -31,8 +31,13 @@ public Control? TargetControl
/// <param name="sender">The <see cref="object"/> that is passed to the action by the behavior. Generally this is <seealso cref="IBehavior.AssociatedObject"/> or a target object.</param>
/// <param name="parameter">The value of this parameter is determined by the caller.</param>
/// <returns>Returns null after executed.</returns>
public virtual object? Execute(object? sender, object? parameter)
public override object? Execute(object? sender, object? parameter)
{
if (!IsEnabled)
{
return false;
}

var control = TargetControl ?? sender as Control;
Dispatcher.UIThread.Post(() => control?.Focus());
return null;
Expand Down
9 changes: 7 additions & 2 deletions src/Avalonia.Xaml.Interactions.Custom/PopupAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Avalonia.Xaml.Interactions.Custom;
/// An action that displays a <see cref="Popup"/> for the associated control when executed.
/// </summary>
/// <remarks>If the associated control is of type <see cref="Control"/> than popup inherits control <see cref="StyledElement.DataContext"/>.</remarks>
public class PopupAction : AvaloniaObject, IAction
public class PopupAction : ActionBase
{
private Popup? _popup;

Expand All @@ -36,8 +36,13 @@ public Control? Child
/// <param name="sender">The <see cref="object"/> that is passed to the action by the behavior. Generally this is <seealso cref="IBehavior.AssociatedObject"/> or a target object.</param>
/// <param name="parameter">The value of this parameter is determined by the caller.</param>
/// <returns>Returns null after executed.</returns>
public virtual object? Execute(object? sender, object? parameter)
public override object? Execute(object? sender, object? parameter)
{
if (!IsEnabled)
{
return false;
}

if (_popup is null)
{
var parent = sender as Control;
Expand Down
9 changes: 7 additions & 2 deletions src/Avalonia.Xaml.Interactions.Custom/RemoveClassAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Avalonia.Xaml.Interactions.Custom;
/// <summary>
/// Removes a specified <see cref="RemoveClassAction.ClassName"/> from <see cref="StyledElement.Classes"/> collection when invoked.
/// </summary>
public class RemoveClassAction : AvaloniaObject, IAction
public class RemoveClassAction : ActionBase
{
/// <summary>
/// Identifies the <seealso cref="ClassName"/> avalonia property.
Expand Down Expand Up @@ -45,8 +45,13 @@ public StyledElement? StyledElement
/// <param name="sender">The <see cref="object"/> that is passed to the action by the behavior. Generally this is <seealso cref="IBehavior.AssociatedObject"/> or a target object.</param>
/// <param name="parameter">The value of this parameter is determined by the caller.</param>
/// <returns>True if the class is successfully added; else false.</returns>
public object Execute(object? sender, object? parameter)
public override object Execute(object? sender, object? parameter)
{
if (!IsEnabled)
{
return false;
}

var target = GetValue(StyledElementProperty) is not null ? StyledElement : sender as StyledElement;
if (target is null || string.IsNullOrEmpty(ClassName))
{
Expand Down
4 changes: 2 additions & 2 deletions src/Avalonia.Xaml.Interactions/Core/CallMethodAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Avalonia.Xaml.Interactions.Core;
/// <summary>
/// An action that calls a method on a specified object when invoked.
/// </summary>
public class CallMethodAction : AvaloniaObject, IAction
public class CallMethodAction : ActionBase
{
private Type? _targetObjectType;
private readonly List<MethodDescriptor> _methodDescriptors = new();
Expand Down Expand Up @@ -109,7 +109,7 @@ private static void TargetObjectChanged(AvaloniaPropertyChangedEventArgs<object?
/// <param name="parameter">The value of this parameter is determined by the caller.</param>
/// <returns>True if the method is called; else false.</returns>
[RequiresUnreferencedCode("This functionality is not compatible with trimming.")]
public virtual object Execute(object? sender, object? parameter)
public override object Execute(object? sender, object? parameter)
{
if (!IsEnabled)
{
Expand Down
9 changes: 7 additions & 2 deletions src/Avalonia.Xaml.Interactions/Core/ChangePropertyAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Avalonia.Xaml.Interactions.Core;
/// <summary>
/// An action that will change a specified property to a specified value when invoked.
/// </summary>
public class ChangePropertyAction : AvaloniaObject, IAction
public class ChangePropertyAction : ActionBase
{
private static readonly char[] s_trimChars = { '(', ')' };
private static readonly char[] s_separator = { '.' };
Expand Down Expand Up @@ -124,8 +124,13 @@ public object? TargetObject
/// <param name="sender">The <see cref="object"/> that is passed to the action by the behavior. Generally this is <seealso cref="IBehavior.AssociatedObject"/> or a target object.</param>
/// <param name="parameter">The value of this parameter is determined by the caller.</param>
/// <returns>True if updating the property value succeeds; else false.</returns>
public virtual object Execute(object? sender, object? parameter)
public override object Execute(object? sender, object? parameter)
{
if (!IsEnabled)
{
return false;
}

object? targetObject;
if (GetValue(TargetObjectProperty) is not null)
{
Expand Down
20 changes: 2 additions & 18 deletions src/Avalonia.Xaml.Interactions/Core/InvokeCommandAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,8 @@ namespace Avalonia.Xaml.Interactions.Core;
/// <summary>
/// Executes a specified <see cref="System.Windows.Input.ICommand"/> when invoked.
/// </summary>
public class InvokeCommandAction : AvaloniaObject, IAction
public class InvokeCommandAction : ActionBase
{
/// <summary>
/// Identifies the <seealso cref="IsEnabled"/> avalonia property.
/// </summary>
public static readonly StyledProperty<bool> IsEnabledProperty =
AvaloniaProperty.Register<InvokeCommandAction, bool>(nameof(IsEnabled), defaultValue: true);

/// <summary>
/// Identifies the <seealso cref="Command"/> avalonia property.
/// </summary>
Expand Down Expand Up @@ -46,16 +40,6 @@ public class InvokeCommandAction : AvaloniaObject, IAction
public static readonly StyledProperty<string?> InputConverterLanguageProperty =
AvaloniaProperty.Register<InvokeCommandAction, string?>(nameof(InputConverterLanguage), string.Empty);

/// <summary>
/// Gets or sets a value indicating whether this instance is enabled.
/// </summary>
/// <value><c>true</c> if this instance is enabled; otherwise, <c>false</c>.</value>
public bool IsEnabled
{
get => GetValue(IsEnabledProperty);
set => SetValue(IsEnabledProperty, value);
}

/// <summary>
/// Gets or sets the command this action should invoke. This is a avalonia property.
/// </summary>
Expand Down Expand Up @@ -119,7 +103,7 @@ public string? InputConverterLanguage
/// <param name="sender">The <see cref="object"/> that is passed to the action by the behavior. Generally this is <seealso cref="IBehavior.AssociatedObject"/> or a target object.</param>
/// <param name="parameter">The value of this parameter is determined by the caller.</param>
/// <returns>True if the command is successfully executed; else false.</returns>
public virtual object Execute(object? sender, object? parameter)
public override object Execute(object? sender, object? parameter)
{
if (IsEnabled != true || Command is null)
{
Expand Down
32 changes: 32 additions & 0 deletions src/Avalonia.Xaml.Interactivity/ActionBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Avalonia.Xaml.Interactivity;

/// <summary>
/// A base class for action that calls a method on a specified object when invoked.
/// </summary>
public abstract class ActionBase : AvaloniaObject, IAction
{
/// <summary>
/// Identifies the <seealso cref="IsEnabled"/> avalonia property.
/// </summary>
public static readonly StyledProperty<bool> IsEnabledProperty =
AvaloniaProperty.Register<ActionBase, bool>(nameof(IsEnabled), defaultValue: true);

/// <summary>
/// Gets or sets a value indicating whether this instance is enabled.
/// </summary>
/// <value><c>true</c> if this instance is enabled; otherwise, <c>false</c>.</value>
public bool IsEnabled
{
get => GetValue(IsEnabledProperty);
set => SetValue(IsEnabledProperty, value);
}

/// <summary>
/// Executes the action.
/// </summary>
/// <param name="sender">The <see cref="object"/> that is passed to the action by the behavior. Generally this is <seealso cref="IBehavior.AssociatedObject"/> or a target object.</param>
/// <param name="parameter">The value of this parameter is determined by the caller.</param>
/// <remarks> An example of parameter usage is EventTriggerBehavior, which passes the EventArgs as a parameter to its actions.</remarks>
/// <returns>Returns the result of the action.</returns>
public abstract object? Execute(object? sender, object? parameter);
}
6 changes: 3 additions & 3 deletions tests/Avalonia.Xaml.Interactivity.UnitTests/StubAction.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Avalonia.Xaml.Interactivity.UnitTests;

public class StubAction(object? returnValue) : AvaloniaObject, IAction
public class StubAction(object? returnValue) : ActionBase
{
public StubAction() : this(null)
{
Expand All @@ -24,11 +24,11 @@ public int ExecuteCount
private set;
}

public object? Execute(object? sender, object? parameter)
public override object? Execute(object? sender, object? parameter)
{
ExecuteCount++;
Sender = sender;
Parameter = parameter;
return returnValue;
}
}
}

0 comments on commit ca91842

Please sign in to comment.