-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProperty.cs
137 lines (123 loc) · 6.1 KB
/
Property.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
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reactive.Disposables;
namespace ReactiveProperties
{
public static partial class Property
{
/// <summary>
/// Creates a property given a property source and a value setter.
/// </summary>
/// <typeparam name="T">The type of the property.</typeparam>
/// <param name="source">The property source.</param>
/// <param name="setValue">The value setter.</param>
/// <returns>The created property.</returns>
public static IProperty<T> Create<T>(IPropertySource<T> source, Action<T> setValue)
{
if (source == null) throw new ArgumentNullException("source");
if (setValue == null) throw new ArgumentNullException("setValue");
return new ExplicitProperty<T>(source, setValue);
}
/// <summary>
/// Creates a property given an initial value and an action that processes a <see cref="SettingData{T}"/> to customize the property value setting operation.
/// </summary>
/// <typeparam name="T">The type of the property.</typeparam>
/// <param name="value">The initial value of the property.</param>
/// <param name="setValue">An action that receives a <see cref="SettingData{T}"/> responsable for setting the property value.</param>
/// <returns>The created property.</returns>
public static IProperty<T> FromValue<T>(T value, Action<SettingData<T>> setValue)
{
if (setValue == null) throw new ArgumentNullException("setValue");
Action notify;
return Create<T>(
PropertySource.Create(() => value, out notify),
desiredValue =>
{
setValue(new SettingData<T>(value, desiredValue, actualValue =>
{
value = actualValue;
notify();
}));
}
);
}
/// <summary>
/// Creates a property given an initial value and notifies the given actions before and after the value changes.
/// </summary>
/// <typeparam name="T">The type of the created property.</typeparam>
/// <param name="value">The initial value of the property.</param>
/// <param name="beforeChange">An action that is invoked before the property value changes.</param>
/// <param name="afterChange">An action that is invoked after the property of the value changes.</param>
/// <param name="comparer">A comparer that determines whether the value of the property is changing.</param>
/// <returns>The created property.</returns>
public static IProperty<T> FromValue<T>(T value, Action<T> beforeChange, Action<T> afterChange, IEqualityComparer<T> comparer)
{
if (beforeChange == null) throw new ArgumentNullException("beforeChange");
if (afterChange == null) throw new ArgumentNullException("afterChange");
if (comparer == null) throw new ArgumentNullException("comparer");
Action notify;
return Create<T>(
PropertySource.Create(() => value, out notify),
newValue =>
{
if (!comparer.Equals(value, newValue))
{
beforeChange(value);
value = newValue;
afterChange(value);
notify();
}
}
);
}
/// <summary>
/// Creates a property given an initial value and notifies the given actions before and after the value changes.
/// </summary>
/// <typeparam name="T">The type of the created property.</typeparam>
/// <param name="value">The initial value of the property.</param>
/// <param name="beforeChange">An action that is invoked before the property value changes.</param>
/// <param name="afterChange">An action that is invoked after the property of the value changes.</param>
/// <returns>The created property.</returns>
public static IProperty<T> FromValue<T>(T value, Action<T> beforeChange, Action<T> afterChange)
{
if (beforeChange == null) throw new ArgumentNullException("beforeChange");
if (afterChange == null) throw new ArgumentNullException("afterChange");
return FromValue(value, beforeChange, afterChange, EqualityComparer<T>.Default);
}
/// <summary>
/// Creates a property given an initial value and a comparer.
/// </summary>
/// <typeparam name="T">The type of the created property.</typeparam>
/// <param name="value">The initial value of the property.</param>
/// <param name="comparer">A comparer that determines whether the value being set is equal to the current property value.</param>
/// <returns>The created property.</returns>
/// <remarks>If the comparer determines that the value being set is the same as the current value, the new value is ignored.</remarks>
public static IProperty<T> FromValue<T>(T value, IEqualityComparer<T> comparer)
{
if (comparer == null) throw new ArgumentNullException("comparer");
Action notify;
return Create(
PropertySource.Create(() => value, out notify),
newValue =>
{
if (!comparer.Equals(value, newValue))
{
value = newValue;
notify();
}
}
);
}
/// <summary>
/// Creates a property with an initial value.
/// </summary>
/// <typeparam name="T">The type of the property.</typeparam>
/// <param name="value">The initial value of the property.</param>
/// <returns>The created property.</returns>
public static IProperty<T> FromValue<T>(T value = default(T))
{
return FromValue(value, EqualityComparer<T>.Default);
}
}
}