@@ -39,7 +39,7 @@ partial class DependencyPropertyDetailsCollection : IDisposable
39
39
private int _entriesLength ;
40
40
private int _minId ;
41
41
private int _maxId ;
42
- private DependencyObjectStore . DefaultValueProvider ? _defaultValueProvider ;
42
+ private List < DependencyObjectStore . DefaultValueProvider > ? _defaultValueProviders = null ;
43
43
44
44
private object ? Owner => _hardOwnerReference ?? _ownerReference . Target ;
45
45
@@ -141,9 +141,9 @@ public DependencyPropertyDetails FindPropertyDetails(DependencyProperty property
141
141
{
142
142
propertyEntry = new DependencyPropertyDetails ( property , _ownerType ) ;
143
143
144
- if ( _defaultValueProvider != null && _defaultValueProvider ( property , out var v ) )
144
+ if ( TryResolveDefaultValueFromProviders ( property , out var value ) )
145
145
{
146
- propertyEntry . SetDefaultValue ( v ) ;
146
+ propertyEntry . SetDefaultValue ( value ) ;
147
147
}
148
148
}
149
149
@@ -178,9 +178,9 @@ public DependencyPropertyDetails FindPropertyDetails(DependencyProperty property
178
178
179
179
ref var propertyEntry = ref Entries ! [ property . UniqueId - _minId ] ;
180
180
propertyEntry = new DependencyPropertyDetails ( property , _ownerType ) ;
181
- if ( _defaultValueProvider != null && _defaultValueProvider ( property , out var v ) )
181
+ if ( TryResolveDefaultValueFromProviders ( property , out var value ) )
182
182
{
183
- propertyEntry . SetValue ( v , DependencyPropertyValuePrecedences . DefaultValue ) ;
183
+ propertyEntry . SetValue ( value , DependencyPropertyValuePrecedences . DefaultValue ) ;
184
184
}
185
185
186
186
return propertyEntry ;
@@ -192,6 +192,24 @@ public DependencyPropertyDetails FindPropertyDetails(DependencyProperty property
192
192
}
193
193
}
194
194
195
+ private bool TryResolveDefaultValueFromProviders ( DependencyProperty property , out object ? value )
196
+ {
197
+ if ( _defaultValueProviders != null )
198
+ {
199
+ for ( int i = _defaultValueProviders . Count - 1 ; i >= 0 ; i -- )
200
+ {
201
+ var provider = _defaultValueProviders [ i ] ;
202
+ if ( provider . Invoke ( property , out var resolvedValue ) )
203
+ {
204
+ value = resolvedValue ;
205
+ return true ;
206
+ }
207
+ }
208
+ }
209
+ value = null ;
210
+ return false ;
211
+ }
212
+
195
213
private void AssignEntries ( DependencyPropertyDetails [ ] newEntries , int newSize )
196
214
{
197
215
ReturnEntriesToPool ( ) ;
@@ -214,9 +232,24 @@ private void ReturnEntriesToPool()
214
232
215
233
internal IEnumerable < DependencyPropertyDetails > GetAllDetails ( ) => Entries . Trim ( ) ;
216
234
235
+ /// <summary>
236
+ /// Adds a default value provider.
237
+ /// </summary>
238
+ /// <param name="provider">Default value provider.</param>
239
+ /// <remarks>
240
+ /// Providers which are registered later have higher precedence.
241
+ /// E.g. when both a derived and base class register their own default
242
+ /// value provider in the constructor for the same property, the derived
243
+ /// class value is used.
244
+ /// </remarks>
217
245
public void RegisterDefaultValueProvider ( DependencyObjectStore . DefaultValueProvider provider )
218
246
{
219
- _defaultValueProvider = provider ;
247
+ if ( _defaultValueProviders == null )
248
+ {
249
+ _defaultValueProviders = new List < DependencyObjectStore . DefaultValueProvider > ( ) ;
250
+ }
251
+
252
+ _defaultValueProviders . Add ( provider ) ;
220
253
}
221
254
222
255
internal void TryEnableHardReferences ( )
0 commit comments