/
ReactiveNSView.cs
142 lines (125 loc) · 4.44 KB
/
ReactiveNSView.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Drawing;
using System.Linq;
using System.Reactive;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Reactive.Subjects;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Threading;
using Splat;
#if UNIFIED
using CoreGraphics;
using Foundation;
using NSView = UIKit.UIView;
using UIKit;
#elif UIKIT
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using NSView = MonoTouch.UIKit.UIView;
#else
using MonoMac.AppKit;
using MonoMac.Foundation;
#endif
namespace ReactiveUI
{
/// <summary>
/// This is an View that is both an NSView and has ReactiveObject powers
/// (i.e. you can call RaiseAndSetIfChanged)
/// </summary>
public class ReactiveView : NSView, IReactiveNotifyPropertyChanged<ReactiveView>, IHandleObservableErrors, IReactiveObject, ICanActivate, ICanForceManualActivation
{
protected ReactiveView() : base()
{
}
protected ReactiveView(NSCoder c) : base(c)
{
}
protected ReactiveView(NSObjectFlag f) : base(f)
{
}
protected ReactiveView(IntPtr handle) : base(handle)
{
}
#if UNIFIED
protected ReactiveView(CGRect frame) : base(frame)
{
}
#else
protected ReactiveView(RectangleF size) : base(size)
{
}
#endif
public event PropertyChangingEventHandler PropertyChanging {
add { PropertyChangingEventManager.AddHandler(this, value); }
remove { PropertyChangingEventManager.RemoveHandler(this, value); }
}
void IReactiveObject.RaisePropertyChanging(PropertyChangingEventArgs args)
{
PropertyChangingEventManager.DeliverEvent(this, args);
}
public event PropertyChangedEventHandler PropertyChanged {
add { PropertyChangedEventManager.AddHandler(this, value); }
remove { PropertyChangedEventManager.RemoveHandler(this, value); }
}
void IReactiveObject.RaisePropertyChanged(PropertyChangedEventArgs args)
{
PropertyChangedEventManager.DeliverEvent(this, args);
}
/// <summary>
/// Represents an Observable that fires *before* a property is about to
/// be changed.
/// </summary>
public IObservable<IReactivePropertyChangedEventArgs<ReactiveView>> Changing {
get { return this.getChangingObservable(); }
}
/// <summary>
/// Represents an Observable that fires *after* a property has changed.
/// </summary>
public IObservable<IReactivePropertyChangedEventArgs<ReactiveView>> Changed {
get { return this.getChangedObservable(); }
}
/// <summary>
/// When this method is called, an object will not fire change
/// notifications (neither traditional nor Observable notifications)
/// until the return value is disposed.
/// </summary>
/// <returns>An object that, when disposed, reenables change
/// notifications.</returns>
public IDisposable SuppressChangeNotifications()
{
return this.suppressChangeNotifications();
}
public IObservable<Exception> ThrownExceptions { get { return this.getThrownExceptionsObservable(); } }
Subject<Unit> activated = new Subject<Unit>();
public IObservable<Unit> Activated { get { return activated; } }
Subject<Unit> deactivated = new Subject<Unit>();
public IObservable<Unit> Deactivated { get { return deactivated; } }
#if UIKIT
public override void WillMoveToSuperview(NSView newsuper)
#else
public override void ViewWillMoveToSuperview(NSView newsuper)
#endif
{
#if UIKIT
base.WillMoveToSuperview(newsuper);
#else
// Xamarin throws ArgumentNullException if newsuper is null
if (newsuper != null) {
base.ViewWillMoveToSuperview(newsuper);
}
#endif
RxApp.MainThreadScheduler.Schedule(() => (newsuper != null ? activated : deactivated).OnNext(Unit.Default));
}
void ICanForceManualActivation.Activate(bool activate)
{
RxApp.MainThreadScheduler.Schedule(() =>
(activate ? activated : deactivated).OnNext(Unit.Default));
}
}
}