Update and add new behaviors
This commit is contained in:
Родитель
218ec6bfdb
Коммит
fea28a56bc
|
@ -11,7 +11,7 @@
|
|||
<Panel Background="Transparent">
|
||||
<i:Interaction.Behaviors>
|
||||
<iac:ShowOnDoubleTappedBehavior TargetControl="TextBoxEdit" />
|
||||
<iac:ShowOnKeyDownTappedBehavior TargetControl="TextBoxEdit" />
|
||||
<iac:ShowOnKeyDownBehavior TargetControl="TextBoxEdit" Key="F2" />
|
||||
</i:Interaction.Behaviors>
|
||||
<TextBox x:Name="TextBoxEdit"
|
||||
IsVisible="False"
|
||||
|
|
|
@ -11,12 +11,6 @@ namespace Avalonia.Xaml.Interactions.Custom;
|
|||
/// </summary>
|
||||
public class ButtonExecuteCommandOnKeyDownBehavior : AttachedToVisualTreeBehavior<Button>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<Key?> KeyProperty =
|
||||
AvaloniaProperty.Register<ButtonExecuteCommandOnKeyDownBehavior, Key?>(nameof(Key));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
@ -26,11 +20,14 @@ public class ButtonExecuteCommandOnKeyDownBehavior : AttachedToVisualTreeBehavio
|
|||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Key? Key
|
||||
{
|
||||
get => GetValue(KeyProperty);
|
||||
set => SetValue(KeyProperty, value);
|
||||
}
|
||||
public static readonly StyledProperty<Key?> KeyProperty =
|
||||
AvaloniaProperty.Register<ButtonExecuteCommandOnKeyDownBehavior, Key?>(nameof(Key));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<KeyGesture?> GestureProperty =
|
||||
AvaloniaProperty.Register<ButtonExecuteCommandOnKeyDownBehavior, KeyGesture?>(nameof(Gesture));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -41,19 +38,31 @@ public class ButtonExecuteCommandOnKeyDownBehavior : AttachedToVisualTreeBehavio
|
|||
set => SetValue(IsEnabledProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Key? Key
|
||||
{
|
||||
get => GetValue(KeyProperty);
|
||||
set => SetValue(KeyProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public KeyGesture? Gesture
|
||||
{
|
||||
get => GetValue(GestureProperty);
|
||||
set => SetValue(GestureProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposables"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposables)
|
||||
{
|
||||
var button = AssociatedObject;
|
||||
if (button is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (button.GetVisualRoot() is InputElement inputRoot)
|
||||
if (AssociatedObject?.GetVisualRoot() is InputElement inputRoot)
|
||||
{
|
||||
var disposable = inputRoot.AddDisposableHandler(InputElement.KeyDownEvent, RootDefaultKeyDown);
|
||||
disposables.Add(disposable);
|
||||
|
@ -62,19 +71,38 @@ public class ButtonExecuteCommandOnKeyDownBehavior : AttachedToVisualTreeBehavio
|
|||
|
||||
private void RootDefaultKeyDown(object? sender, KeyEventArgs e)
|
||||
{
|
||||
var button = AssociatedObject;
|
||||
if (button is null)
|
||||
var haveKey = Key is not null && e.Key == Key;
|
||||
var haveGesture = Gesture is not null && Gesture.Matches(e);
|
||||
|
||||
if (!haveKey && !haveGesture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Key is { } && e.Key == Key && button.IsVisible && button.IsEnabled && IsEnabled)
|
||||
if (AssociatedObject is { } button)
|
||||
{
|
||||
if (!e.Handled && button.Command?.CanExecute(button.CommandParameter) == true)
|
||||
{
|
||||
button.Command.Execute(button.CommandParameter);
|
||||
e.Handled = true;
|
||||
}
|
||||
ExecuteCommand(button);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ExecuteCommand(Button button)
|
||||
{
|
||||
if (!IsEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (button is not { IsVisible: true, IsEnabled: true })
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (button.Command?.CanExecute(button.CommandParameter) != true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
button.Command.Execute(button.CommandParameter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,12 @@ namespace Avalonia.Xaml.Interactions.Custom;
|
|||
/// </summary>
|
||||
public abstract class ExecuteCommandBehaviorBase : AttachedToVisualTreeBehavior<Control>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<bool> IsEnabledProperty =
|
||||
AvaloniaProperty.Register<ExecuteCommandBehaviorBase, bool>(nameof(IsEnabled), true);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
@ -34,6 +40,15 @@ public abstract class ExecuteCommandBehaviorBase : AttachedToVisualTreeBehavior<
|
|||
public static readonly StyledProperty<Control?> FocusControlProperty =
|
||||
AvaloniaProperty.Register<ExecuteCommandBehaviorBase, Control?>(nameof(CommandParameter));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool IsEnabled
|
||||
{
|
||||
get => GetValue(IsEnabledProperty);
|
||||
set => SetValue(IsEnabledProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
@ -77,6 +92,11 @@ public abstract class ExecuteCommandBehaviorBase : AttachedToVisualTreeBehavior<
|
|||
/// <returns></returns>
|
||||
protected bool ExecuteCommand()
|
||||
{
|
||||
if (!IsEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AssociatedObject is not { IsVisible: true, IsEnabled: true })
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -20,13 +20,16 @@ public class ExecuteCommandOnActivatedBehavior : ExecuteCommandBehaviorBase
|
|||
{
|
||||
var mainWindow = lifetime.MainWindow;
|
||||
|
||||
var dispose = Observable
|
||||
.FromEventPattern(mainWindow, nameof(mainWindow.Activated))
|
||||
.Subscribe(new AnonymousObserver<EventPattern<object>>(e =>
|
||||
{
|
||||
ExecuteCommand();
|
||||
}));
|
||||
disposable.Add(dispose);
|
||||
if (mainWindow is not null)
|
||||
{
|
||||
var dispose = Observable
|
||||
.FromEventPattern(mainWindow, nameof(mainWindow.Activated))
|
||||
.Subscribe(new AnonymousObserver<EventPattern<object>>(e =>
|
||||
{
|
||||
ExecuteCommand();
|
||||
}));
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,4 +40,3 @@ public class ExecuteCommandOnDoubleTappedBehavior : ExecuteCommandBehaviorBase
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnGotFocusBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
InputElement.GotFocusEvent,
|
||||
AssociatedObject_GotFocus,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_GotFocus(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnHoldingBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.HoldingEvent,
|
||||
AssociatedObject_Holding,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_Holding(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -78,3 +78,78 @@ public class ExecuteCommandOnKeyDownBehavior : ExecuteCommandBehaviorBase
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnKeyUpBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<Key?> KeyProperty =
|
||||
AvaloniaProperty.Register<ExecuteCommandOnKeyDownBehavior, Key?>(nameof(Key));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<KeyGesture?> GestureProperty =
|
||||
AvaloniaProperty.Register<ExecuteCommandOnKeyDownBehavior, KeyGesture?>(nameof(Gesture));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Key? Key
|
||||
{
|
||||
get => GetValue(KeyProperty);
|
||||
set => SetValue(KeyProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public KeyGesture? Gesture
|
||||
{
|
||||
get => GetValue(GestureProperty);
|
||||
set => SetValue(GestureProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
InputElement.KeyUpEvent,
|
||||
OnKeyUp,
|
||||
RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnKeyUp(object? sender, KeyEventArgs e)
|
||||
{
|
||||
var haveKey = Key is not null && e.Key == Key;
|
||||
var haveGesture = Gesture is not null && Gesture.Matches(e);
|
||||
|
||||
if (!haveKey && !haveGesture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPinchBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.PinchEvent,
|
||||
AssociatedObject_Pinch,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_Pinch(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPinchEndedBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.PinchEndedEvent,
|
||||
AssociatedObject_PinchEnded,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_PinchEnded(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPointerCaptureLostBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
InputElement.PointerCaptureLostEvent,
|
||||
AssociatedObject_PointerCaptureLost,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_PointerCaptureLost(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPointerEnteredBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
InputElement.PointerEnteredEvent,
|
||||
AssociatedObject_PointerEntered,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_PointerEntered(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPointerExitedBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
InputElement.PointerExitedEvent,
|
||||
AssociatedObject_PointerExited,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_PointerExited(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPointerMovedBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
InputElement.PointerMovedEvent,
|
||||
AssociatedObject_PointerMoved,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_PointerMoved(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPointerPressedBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
InputElement.PointerPressedEvent,
|
||||
AssociatedObject_PointerPressed,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_PointerPressed(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPointerReleasedBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
InputElement.PointerReleasedEvent,
|
||||
AssociatedObject_PointerReleased,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_PointerReleased(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPointerTouchPadGestureMagnifyBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.PointerTouchPadGestureMagnifyEvent,
|
||||
AssociatedObject_PointerTouchPadGestureMagnify,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_PointerTouchPadGestureMagnify(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPointerTouchPadGestureRotateBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.PointerTouchPadGestureRotateEvent,
|
||||
AssociatedObject_PointerTouchPadGestureRotate,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_PointerTouchPadGestureRotate(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPointerTouchPadGestureSwipeBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.PointerTouchPadGestureSwipeEvent,
|
||||
AssociatedObject_PointerTouchPadGestureSwipe,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_PointerTouchPadGestureSwipe(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPointerWheelChangedBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
InputElement.PointerWheelChangedEvent,
|
||||
AssociatedObject_PointerWheelChanged,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_PointerWheelChanged(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPullGestureBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.PullGestureEvent,
|
||||
AssociatedObject_PullGesture,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_PullGesture(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnPullGestureEndedBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.PullGestureEndedEvent,
|
||||
AssociatedObject_PullGestureEnded,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_PullGestureEnded(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnRightTappedBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.RightTappedEvent,
|
||||
AssociatedObject_RightTapped,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_RightTapped(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnScrollGestureBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.ScrollGestureEvent,
|
||||
AssociatedObject_ScrollGesture,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_ScrollGesture(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnScrollGestureEndedBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.ScrollGestureEndedEvent,
|
||||
AssociatedObject_ScrollGestureEnded,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_ScrollGestureEnded(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnScrollGestureInertiaStartingBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.ScrollGestureInertiaStartingEvent,
|
||||
AssociatedObject_ScrollGestureInertiaStarting,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_ScrollGestureInertiaStarting(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnTappedBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.TappedEvent,
|
||||
AssociatedObject_Tapped,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_Tapped(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnTextInputBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
InputElement.TextInputEvent,
|
||||
AssociatedObject_TextInput,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_TextInput(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExecuteCommandOnTextInputMethodClientRequestedBehavior : ExecuteCommandBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
InputElement.TextInputMethodClientRequestedEvent,
|
||||
AssociatedObject_TextInputMethodClientRequested,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_TextInputMethodClientRequested(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecuteCommand())
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Threading;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class ShowBehaviorBase : AttachedToVisualTreeBehavior<Control>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<bool> IsEnabledProperty =
|
||||
AvaloniaProperty.Register<ShowBehaviorBase, bool>(nameof(IsEnabled), true);
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <seealso cref="TargetControl"/> avalonia property.
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<Control?> TargetControlProperty =
|
||||
AvaloniaProperty.Register<ShowBehaviorBase, Control?>(nameof(TargetControl));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool IsEnabled
|
||||
{
|
||||
get => GetValue(IsEnabledProperty);
|
||||
set => SetValue(IsEnabledProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target control. This is a avalonia property.
|
||||
/// </summary>
|
||||
[ResolveByName]
|
||||
public Control? TargetControl
|
||||
{
|
||||
get => GetValue(TargetControlProperty);
|
||||
set => SetValue(TargetControlProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected bool Show()
|
||||
{
|
||||
if (IsEnabled && TargetControl is { IsVisible: false })
|
||||
{
|
||||
TargetControl.SetCurrentValue(Visual.IsVisibleProperty, true);
|
||||
|
||||
Dispatcher.UIThread.Post(() => TargetControl.Focus());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,51 +1,34 @@
|
|||
using Avalonia.Controls;
|
||||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Threading;
|
||||
using Avalonia.Xaml.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
/// A behavior that allows to show control on double tapped event.
|
||||
/// </summary>
|
||||
public class ShowOnDoubleTappedBehavior : Behavior<Control>
|
||||
public class ShowOnDoubleTappedBehavior : ShowBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies the <seealso cref="TargetControl"/> avalonia property.
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<Control?> TargetControlProperty =
|
||||
AvaloniaProperty.Register<ShowOnDoubleTappedBehavior, Control?>(nameof(TargetControl));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target control. This is a avalonia property.
|
||||
/// </summary>
|
||||
[ResolveByName]
|
||||
public Control? TargetControl
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
get => GetValue(TargetControlProperty);
|
||||
set => SetValue(TargetControlProperty, value);
|
||||
}
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.DoubleTappedEvent,
|
||||
AssociatedObject_DoubleTapped,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnAttachedToVisualTree()
|
||||
{
|
||||
AssociatedObject?.AddHandler(Gestures.DoubleTappedEvent, AssociatedObject_DoubleTapped,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnDetachedFromVisualTree()
|
||||
{
|
||||
AssociatedObject?.RemoveHandler(Gestures.DoubleTappedEvent, AssociatedObject_DoubleTapped);
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_DoubleTapped(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (TargetControl is {IsVisible: false})
|
||||
{
|
||||
TargetControl.IsVisible = true;
|
||||
Dispatcher.UIThread.Post(() => TargetControl.Focus());
|
||||
}
|
||||
Show();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
/// A behavior that allows to show control on key down event.
|
||||
/// </summary>
|
||||
public class ShowOnKeyDownBehavior : ShowBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies the <seealso cref="Key"/> avalonia property.
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<Key?> KeyProperty =
|
||||
AvaloniaProperty.Register<ShowOnKeyDownBehavior, Key?>(nameof(Key));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<KeyGesture?> GestureProperty =
|
||||
AvaloniaProperty.Register<ShowOnKeyDownBehavior, KeyGesture?>(nameof(Gesture));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the key. This is a avalonia property.
|
||||
/// </summary>
|
||||
public Key? Key
|
||||
{
|
||||
get => GetValue(KeyProperty);
|
||||
set => SetValue(KeyProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public KeyGesture? Gesture
|
||||
{
|
||||
get => GetValue(GestureProperty);
|
||||
set => SetValue(GestureProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
InputElement.KeyDownEvent,
|
||||
AssociatedObject_KeyDown,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_KeyDown(object? sender, KeyEventArgs e)
|
||||
{
|
||||
var haveKey = Key is not null && e.Key == Key;
|
||||
var haveGesture = Gesture is not null && Gesture.Matches(e);
|
||||
|
||||
if (!haveKey && !haveGesture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Show();
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Threading;
|
||||
using Avalonia.Xaml.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
/// A behavior that allows to show control on key down event.
|
||||
/// </summary>
|
||||
public class ShowOnKeyDownTappedBehavior : Behavior<Control>
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies the <seealso cref="TargetControl"/> avalonia property.
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<Control?> TargetControlProperty =
|
||||
AvaloniaProperty.Register<ShowOnKeyDownTappedBehavior, Control?>(nameof(TargetControl));
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <seealso cref="Key"/> avalonia property.
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<Key> KeyProperty =
|
||||
AvaloniaProperty.Register<ShowOnKeyDownTappedBehavior, Key>(nameof(Key), Key.F2);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target control. This is a avalonia property.
|
||||
/// </summary>
|
||||
[ResolveByName]
|
||||
public Control? TargetControl
|
||||
{
|
||||
get => GetValue(TargetControlProperty);
|
||||
set => SetValue(TargetControlProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the key. This is a avalonia property.
|
||||
/// </summary>
|
||||
public Key Key
|
||||
{
|
||||
get => GetValue(KeyProperty);
|
||||
set => SetValue(KeyProperty, value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnAttachedToVisualTree()
|
||||
{
|
||||
AssociatedObject?.AddHandler(InputElement.KeyDownEvent, AssociatedObject_KeyDown,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnDetachedFromVisualTree()
|
||||
{
|
||||
AssociatedObject?.RemoveHandler(InputElement.KeyDownEvent, AssociatedObject_KeyDown);
|
||||
}
|
||||
|
||||
private void AssociatedObject_KeyDown(object? sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key && TargetControl is {IsVisible: false})
|
||||
{
|
||||
TargetControl.IsVisible = true;
|
||||
Dispatcher.UIThread.Post(() => TargetControl.Focus());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using System.Reactive.Disposables;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Avalonia.Xaml.Interactions.Custom;
|
||||
|
||||
/// <summary>
|
||||
/// A behavior that allows to show control on tapped event.
|
||||
/// </summary>
|
||||
public class ShowOnTappedBehavior : ShowBehaviorBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposable"></param>
|
||||
protected override void OnAttachedToVisualTree(CompositeDisposable disposable)
|
||||
{
|
||||
var dispose = AssociatedObject?
|
||||
.AddDisposableHandler(
|
||||
Gestures.TappedEvent,
|
||||
AssociatedObject_Tapped,
|
||||
RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
if (dispose is not null)
|
||||
{
|
||||
disposable.Add(dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssociatedObject_Tapped(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Show();
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче