9
9
10
10
using System ;
11
11
using System . Collections . Generic ;
12
+ using System . Linq . Expressions ;
12
13
using System . Runtime . CompilerServices ;
13
14
using Microsoft . Toolkit . Mvvm . Messaging ;
14
15
using Microsoft . Toolkit . Mvvm . Messaging . Messages ;
@@ -140,7 +141,18 @@ protected virtual void Broadcast<T>(T oldValue, T newValue, string? propertyName
140
141
/// </remarks>
141
142
protected bool SetProperty < T > ( ref T field , T newValue , bool broadcast , [ CallerMemberName ] string ? propertyName = null )
142
143
{
143
- return SetProperty ( ref field , newValue , EqualityComparer < T > . Default , broadcast , propertyName ) ;
144
+ T oldValue = field ;
145
+
146
+ // We duplicate the code as in the base class here to leverage
147
+ // the intrinsics support for EqualityComparer<T>.Default.Equals.
148
+ bool propertyChanged = SetProperty ( ref field , newValue , propertyName ) ;
149
+
150
+ if ( propertyChanged && broadcast )
151
+ {
152
+ Broadcast ( oldValue , newValue , propertyName ) ;
153
+ }
154
+
155
+ return propertyChanged ;
144
156
}
145
157
146
158
/// <summary>
@@ -158,21 +170,16 @@ protected bool SetProperty<T>(ref T field, T newValue, bool broadcast, [CallerMe
158
170
/// <returns><see langword="true"/> if the property was changed, <see langword="false"/> otherwise.</returns>
159
171
protected bool SetProperty < T > ( ref T field , T newValue , IEqualityComparer < T > comparer , bool broadcast , [ CallerMemberName ] string ? propertyName = null )
160
172
{
161
- if ( ! broadcast )
162
- {
163
- return SetProperty ( ref field , newValue , comparer , propertyName ) ;
164
- }
165
-
166
173
T oldValue = field ;
167
174
168
- if ( SetProperty ( ref field , newValue , comparer , propertyName ) )
175
+ bool propertyChanged = SetProperty ( ref field , newValue , comparer , propertyName ) ;
176
+
177
+ if ( propertyChanged && broadcast )
169
178
{
170
179
Broadcast ( oldValue , newValue , propertyName ) ;
171
-
172
- return true ;
173
180
}
174
181
175
- return false ;
182
+ return propertyChanged ;
176
183
}
177
184
178
185
/// <summary>
@@ -216,19 +223,61 @@ protected bool SetProperty<T>(T oldValue, T newValue, Action<T> callback, bool b
216
223
/// <returns><see langword="true"/> if the property was changed, <see langword="false"/> otherwise.</returns>
217
224
protected bool SetProperty < T > ( T oldValue , T newValue , IEqualityComparer < T > comparer , Action < T > callback , bool broadcast , [ CallerMemberName ] string ? propertyName = null )
218
225
{
219
- if ( ! broadcast )
226
+ bool propertyChanged = SetProperty ( oldValue , newValue , comparer , callback , propertyName ) ;
227
+
228
+ if ( propertyChanged && broadcast )
220
229
{
221
- return SetProperty ( oldValue , newValue , comparer , callback , propertyName ) ;
230
+ Broadcast ( oldValue , newValue , propertyName ) ;
222
231
}
223
232
224
- if ( SetProperty ( oldValue , newValue , comparer , callback , propertyName ) )
233
+ return propertyChanged ;
234
+ }
235
+
236
+ /// <summary>
237
+ /// Compares the current and new values for a given nested property. If the value has changed,
238
+ /// raises the <see cref="ObservableObject.PropertyChanging"/> event, updates the property and then raises the
239
+ /// <see cref="ObservableObject.PropertyChanged"/> event. The behavior mirrors that of
240
+ /// <see cref="ObservableObject.SetProperty{T}(Expression{Func{T}},T,string)"/>, with the difference being that this
241
+ /// method is used to relay properties from a wrapped model in the current instance. For more info, see the docs for
242
+ /// <see cref="ObservableObject.SetProperty{T}(Expression{Func{T}},T,string)"/>.
243
+ /// </summary>
244
+ /// <typeparam name="T">The type of property to set.</typeparam>
245
+ /// <param name="propertyExpression">An <see cref="Expression{TDelegate}"/> returning the property to update.</param>
246
+ /// <param name="newValue">The property's value after the change occurred.</param>
247
+ /// <param name="broadcast">If <see langword="true"/>, <see cref="Broadcast{T}"/> will also be invoked.</param>
248
+ /// <param name="propertyName">(optional) The name of the property that changed.</param>
249
+ /// <returns><see langword="true"/> if the property was changed, <see langword="false"/> otherwise.</returns>
250
+ protected bool SetProperty < T > ( Expression < Func < T > > propertyExpression , T newValue , bool broadcast , [ CallerMemberName ] string ? propertyName = null )
251
+ {
252
+ return SetProperty ( propertyExpression , newValue , EqualityComparer < T > . Default , broadcast , propertyName ) ;
253
+ }
254
+
255
+ /// <summary>
256
+ /// Compares the current and new values for a given nested property. If the value has changed,
257
+ /// raises the <see cref="ObservableObject.PropertyChanging"/> event, updates the property and then raises the
258
+ /// <see cref="ObservableObject.PropertyChanged"/> event. The behavior mirrors that of
259
+ /// <see cref="ObservableObject.SetProperty{T}(Expression{Func{T}},T,IEqualityComparer{T},string)"/>,
260
+ /// with the difference being that this method is used to relay properties from a wrapped model in the
261
+ /// current instance. For more info, see the docs for
262
+ /// <see cref="ObservableObject.SetProperty{T}(Expression{Func{T}},T,IEqualityComparer{T},string)"/>.
263
+ /// </summary>
264
+ /// <typeparam name="T">The type of property to set.</typeparam>
265
+ /// <param name="propertyExpression">An <see cref="Expression{TDelegate}"/> returning the property to update.</param>
266
+ /// <param name="newValue">The property's value after the change occurred.</param>
267
+ /// <param name="comparer">The <see cref="IEqualityComparer{T}"/> instance to use to compare the input values.</param>
268
+ /// <param name="broadcast">If <see langword="true"/>, <see cref="Broadcast{T}"/> will also be invoked.</param>
269
+ /// <param name="propertyName">(optional) The name of the property that changed.</param>
270
+ /// <returns><see langword="true"/> if the property was changed, <see langword="false"/> otherwise.</returns>
271
+ protected bool SetProperty < T > ( Expression < Func < T > > propertyExpression , T newValue , IEqualityComparer < T > comparer , bool broadcast , [ CallerMemberName ] string ? propertyName = null )
272
+ {
273
+ bool propertyChanged = SetProperty ( propertyExpression , newValue , comparer , out T oldValue , propertyName ) ;
274
+
275
+ if ( propertyChanged && broadcast )
225
276
{
226
277
Broadcast ( oldValue , newValue , propertyName ) ;
227
-
228
- return true ;
229
278
}
230
279
231
- return false ;
280
+ return propertyChanged ;
232
281
}
233
282
}
234
283
}
0 commit comments