Closed ShadowsInRain closed 3 years ago
@ShadowsInRain
Can you try this:
using System;
using Avalonia.Xaml.Interactivity;
namespace Avalonia.Xaml.Interactions.Custom
{
/// <summary>
/// A behavior that performs actions when the bound data produces new value.
/// </summary>
public sealed class ValueChangedTriggerBehavior : Trigger
{
static ValueChangedTriggerBehavior()
{
BindingProperty.Changed.Subscribe(e => OnValueChanged(e.Sender, e));
}
/// <summary>
/// Identifies the <seealso cref="Binding"/> avalonia property.
/// </summary>
public static readonly StyledProperty<object?> BindingProperty =
AvaloniaProperty.Register<ValueChangedTriggerBehavior, object?>(nameof(Binding));
/// <summary>
/// Gets or sets the bound object that the <see cref="ValueChangedTriggerBehavior"/> will listen to. This is a avalonia property.
/// </summary>
public object? Binding
{
get => GetValue(BindingProperty);
set => SetValue(BindingProperty, value);
}
private static void OnValueChanged(IAvaloniaObject avaloniaObject, AvaloniaPropertyChangedEventArgs args)
{
if (!(avaloniaObject is ValueChangedTriggerBehavior behavior) || behavior.AssociatedObject is null)
{
return;
}
var binding = behavior.Binding;
if (binding is { })
{
Interaction.ExecuteActions(behavior.AssociatedObject, behavior.Actions, args);
}
}
}
}
@ShadowsInRain https://github.com/wieslawsoltes/AvaloniaBehaviors/pull/69
@wieslawsoltes Thanks, it works. I did something similar, except that I subscribe directly to the observable. I was afraid that binding would emit distinct values only, but that does not seems to be the case.
Avalonia allows to bind to observables and tasks with caret
^
syntax, e.g.{Binding WhenFocused^}
.Problem is, there is no easy way to subscribe to streams.
DataTriggerBehavior
doesn't work without value to compare to, so I have either to wrapUnit
observables (with e.g.IObservable<bool>
) or to shoehornUnit.Default
into a binding.EventTriggerBehavior
seems more suitable for that, but currently it's concerned with events only.Ideally I'd like to write: