/
EventToReactiveProperty.cs
101 lines (88 loc) · 3.24 KB
/
EventToReactiveProperty.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
using System;
using System.Reactive;
using System.Reactive.Subjects;
using System.Windows.Input;
using System.Reactive.Linq;
using Reactive.Bindings.Extensions;
#if NETFX_CORE
using Windows.UI.Xaml.Markup;
using Windows.UI.Xaml;
using System.Collections.Generic;
#else
using System.Windows.Interactivity;
using System.Windows.Markup;
using System.ComponentModel;
using System.Windows;
using System.Collections.Generic;
#endif
namespace Reactive.Bindings.Interactivity
{
/// <summary>
/// Converts EventArgs to object
/// </summary>
#if NETFX_CORE
[ContentProperty(Name = nameof(EventToReactiveProperty.Converters))]
#else
[ContentProperty(nameof(EventToReactiveProperty.Converters))]
#endif
public class EventToReactiveProperty : TriggerAction<FrameworkElement>
{
private readonly Subject<object> source = new Subject<object>();
private IDisposable disposable;
public IReactiveProperty ReactiveProperty
{
get { return (IReactiveProperty)GetValue(ReactivePropertyProperty); }
set { SetValue(ReactivePropertyProperty, value); }
}
// Using a DependencyProperty as the backing store for Command. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ReactivePropertyProperty =
DependencyProperty.Register(nameof(EventToReactiveProperty.ReactiveProperty), typeof(IReactiveProperty), typeof(EventToReactiveProperty), new PropertyMetadata(null));
/// <summary>
/// Ignore EventArgs. If value is false then uses Unit.Default.
/// </summary>
public bool IgnoreEventArgs { get; set; }
private List<IEventToReactiveConverter> converters = new List<IEventToReactiveConverter>();
/// <summary>
/// set and get Value converter.
/// </summary>
public List<IEventToReactiveConverter> Converters { get { return this.converters; } }
// Using a DependencyProperty as the backing store for Converter. This enables animation, styling, binding, etc...
protected override void OnDetaching()
{
base.OnDetaching();
this.disposable?.Dispose();
}
protected override void Invoke(object parameter)
{
if (this.disposable == null)
{
IObservable<object> ox = this.source;
foreach (var c in this.Converters)
{
c.AssociateObject = this.AssociatedObject;
ox = c.Convert(ox);
}
this.disposable = ox
.ObserveOnUIDispatcher()
.Where(_ => this.ReactiveProperty != null)
.Subscribe(x => this.ReactiveProperty.Value = x);
}
if (!this.IgnoreEventArgs)
{
this.source.OnNext(parameter);
}
else
{
this.source.OnNext(Unit.Default);
}
}
private class DefaultConverter : IEventToReactiveConverter
{
public object AssociateObject { get; set; }
public IObservable<object> Convert(IObservable<object> source)
{
return source;
}
}
}
}