Skip to content

Commit

Permalink
Merge pull request #264 from runceel/main
Browse files Browse the repository at this point in the history
v7.11.0
  • Loading branch information
runceel authored May 31, 2021
2 parents 418aae5 + 34f0ab3 commit 28f8f6b
Show file tree
Hide file tree
Showing 8 changed files with 620 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
using System.Reactive.Subjects;
using System.Windows.Input;
using System.Reactive.Linq;
using System.Reactive.Disposables;
using Reactive.Bindings.Extensions;
using System.Collections.Generic;

#if NETFX_CORE
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Markup;
using Windows.UI.Xaml;
#else
using System.Windows.Data;
using System.Windows.Markup;
using System.Windows;
using Microsoft.Xaml.Behaviors;
Expand All @@ -29,8 +33,9 @@ namespace Reactive.Bindings.Interactivity
public class EventToReactiveCommand : TriggerAction<FrameworkElement>
{
private readonly Subject<object> source = new Subject<object>();
private readonly Subject<EventArgs> autoEnableSource = new Subject<EventArgs>();

private IDisposable disposable;
private CompositeDisposable Disposable { get; } = new CompositeDisposable();

/// <summary>
/// Gets or sets the command.
Expand All @@ -42,11 +47,49 @@ public ICommand Command
set { SetValue(CommandProperty, value); }
}

#if NETFX_CORE
/// <summary>
/// The command property
/// </summary>
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register(nameof(EventToReactiveCommand.Command), typeof(ICommand), typeof(EventToReactiveCommand),
new PropertyMetadata(null, (d, e) => ((EventToReactiveCommand)d).OnCommandInitialized(e)));

private void OnCommandInitialized(DependencyPropertyChangedEventArgs e)
{
if (e.OldValue == null && e.NewValue != null)
{
SetSubScribes();
}
}
#else
/// <summary>
/// The command property
/// </summary>
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register(nameof(EventToReactiveCommand.Command), typeof(ICommand), typeof(EventToReactiveCommand), new PropertyMetadata(null));
#endif

/// <summary>
/// Gets or sets whether or not AssociatedObject.IsEnabled automatically follow the Command's CanExecute.
/// </summary>
public bool AutoEnable
{
get { return (bool)GetValue(AutoEnableProperty); }
set { SetValue(AutoEnableProperty, value); }
}

/// <summary>
/// The AutoEnable Property
/// </summary>
public static readonly DependencyProperty AutoEnableProperty =
DependencyProperty.Register(nameof(EventToReactiveCommand.AutoEnable), typeof(bool), typeof(EventToReactiveCommand),
new PropertyMetadata(true, (d, _) => ((EventToReactiveCommand)d).OnAllowDisableChanged()));

private void OnAllowDisableChanged()
{
autoEnableSource.OnNext(EventArgs.Empty);
}

/// <summary>
/// Ignore EventArgs. If value is false then uses Unit.Default.
Expand All @@ -60,13 +103,66 @@ public ICommand Command
/// </summary>
public List<IEventToReactiveConverter> Converters { get { return converters; } }

private BindingExpression expression;

/// <summary>
/// Called when [attached].
/// </summary>
protected override void OnAttached()
{
base.OnAttached();
#if !NETFX_CORE
SetSubScribes();
#endif
}

private void SetSubScribes()
{
IObservable<object> ox = source;
foreach (var c in Converters)
{
c.AssociateObject = AssociatedObject;
ox = c.Convert(ox);
}
ox
.ObserveOnUIDispatcher()
.Where(_ => Command != null)
.Subscribe(x => Command.Execute(x)).AddTo(Disposable);

#if NETFX_CORE
if (!(AssociatedObject is Control control)) return;
var isEnabledProperty = Control.IsEnabledProperty;
#else
var isEnabledProperty = FrameworkElement.IsEnabledProperty;
var control = AssociatedObject;
#endif
expression = AssociatedObject.GetBindingExpression(isEnabledProperty);

Command?.CanExecuteChangedAsObservable().Merge(autoEnableSource)
.Subscribe(_ =>
{
if (AutoEnable)
{
control.IsEnabled = Command.CanExecute(null);
}
else if (expression != null)
{
control.SetBinding(isEnabledProperty, expression.ParentBinding);
}
else
{
control.IsEnabled = true;
}
}).AddTo(Disposable);
}

/// <summary>
/// Called when [detaching].
/// </summary>
protected override void OnDetaching()
{
base.OnDetaching();
disposable?.Dispose();
Disposable?.Dispose();
}

/// <summary>
Expand All @@ -75,18 +171,9 @@ protected override void OnDetaching()
/// <param name="parameter">The parameter.</param>
protected override void Invoke(object parameter)
{
if (disposable == null)
if (!Command?.CanExecute(parameter) ?? true)
{
IObservable<object> ox = source;
foreach (var c in Converters)
{
c.AssociateObject = AssociatedObject;
ox = c.Convert(ox);
}
disposable = ox
.ObserveOnUIDispatcher()
.Where(_ => Command != null)
.Subscribe(x => Command.Execute(x));
return;
}

if (!IgnoreEventArgs)
Expand Down
Loading

0 comments on commit 28f8f6b

Please sign in to comment.