Skip to content

Commit d39362b

Browse files
committed
fix: Allow multiple default value providers
1 parent 540091f commit d39362b

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

src/Uno.UI/UI/Xaml/DependencyPropertyDetails.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ private bool SetValueFast(object? value, DependencyPropertyValuePrecedences prec
184184
return false;
185185
}
186186

187-
internal void SetDefaultValue(object defaultValue)
187+
internal void SetDefaultValue(object? defaultValue)
188188
{
189189
_defaultValue = defaultValue;
190190
_flags |= Flags.DefaultValueSet;

src/Uno.UI/UI/Xaml/DependencyPropertyDetailsCollection.cs

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ partial class DependencyPropertyDetailsCollection : IDisposable
3939
private int _entriesLength;
4040
private int _minId;
4141
private int _maxId;
42-
private DependencyObjectStore.DefaultValueProvider? _defaultValueProvider;
42+
private List<DependencyObjectStore.DefaultValueProvider>? _defaultValueProviders = null;
4343

4444
private object? Owner => _hardOwnerReference ?? _ownerReference.Target;
4545

@@ -141,9 +141,9 @@ public DependencyPropertyDetails FindPropertyDetails(DependencyProperty property
141141
{
142142
propertyEntry = new DependencyPropertyDetails(property, _ownerType);
143143

144-
if(_defaultValueProvider != null && _defaultValueProvider(property, out var v))
144+
if (TryResolveDefaultValueFromProviders(property, out var value))
145145
{
146-
propertyEntry.SetDefaultValue(v);
146+
propertyEntry.SetDefaultValue(value);
147147
}
148148
}
149149

@@ -178,9 +178,9 @@ public DependencyPropertyDetails FindPropertyDetails(DependencyProperty property
178178

179179
ref var propertyEntry = ref Entries![property.UniqueId - _minId];
180180
propertyEntry = new DependencyPropertyDetails(property, _ownerType);
181-
if (_defaultValueProvider != null && _defaultValueProvider(property, out var v))
181+
if (TryResolveDefaultValueFromProviders(property, out var value))
182182
{
183-
propertyEntry.SetValue(v, DependencyPropertyValuePrecedences.DefaultValue);
183+
propertyEntry.SetValue(value, DependencyPropertyValuePrecedences.DefaultValue);
184184
}
185185

186186
return propertyEntry;
@@ -192,6 +192,24 @@ public DependencyPropertyDetails FindPropertyDetails(DependencyProperty property
192192
}
193193
}
194194

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+
195213
private void AssignEntries(DependencyPropertyDetails[] newEntries, int newSize)
196214
{
197215
ReturnEntriesToPool();
@@ -214,9 +232,24 @@ private void ReturnEntriesToPool()
214232

215233
internal IEnumerable<DependencyPropertyDetails> GetAllDetails() => Entries.Trim();
216234

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>
217245
public void RegisterDefaultValueProvider(DependencyObjectStore.DefaultValueProvider provider)
218246
{
219-
_defaultValueProvider = provider;
247+
if (_defaultValueProviders == null)
248+
{
249+
_defaultValueProviders = new List<DependencyObjectStore.DefaultValueProvider>();
250+
}
251+
252+
_defaultValueProviders.Add(provider);
220253
}
221254

222255
internal void TryEnableHardReferences()

0 commit comments

Comments
 (0)