diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceDictionary.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceDictionary.cs
index 00c3e73fcf4..445eea5693c 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceDictionary.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceDictionary.cs
@@ -109,7 +109,7 @@ private void CopyToWithoutLock(DictionaryEntry[] array, int arrayIndex)
entry.Value = value; // refresh the entry value in case it was changed in the previous call
}
}
-
+
// This is set when the RD is loaded from unsafe xps doc. This will be checked while creating reader for RD source.
internal bool IsUnsafe { get; set; }
@@ -157,7 +157,7 @@ public Uri Source
// that it is being passed down by the Baml parsing code, and it is trying to give us more
// information to avoid possible ambiguities in assembly resolving. Use the VersionedUri
// to resolve, and the set _source to the OriginalUri so we don't change the return of Source property.
- // The versioned Uri is not stored, if the version info is needed while debugging, once this method
+ // The versioned Uri is not stored, if the version info is needed while debugging, once this method
// returns _reader should be set, from there BamlSchemaContext.LocalAssembly contains the version info.
if (uriWrapper == null)
{
@@ -169,10 +169,10 @@ public Uri Source
_source = uriWrapper.OriginalUri;
sourceUri = uriWrapper.VersionedUri;
}
-
+
Clear();
-
-
+
+
Uri uri = BindUriHelper.GetResolvedUri(_baseUri, sourceUri);
WebRequest request = WpfWebRequestHelper.CreateRequest(uri);
@@ -1737,10 +1737,7 @@ private object FetchResource(
{
// Cache the deferredResourceReference so that it can be validated
// in case of a dictionary change prior to its inflation
- if (_deferredResourceReferences == null)
- {
- _deferredResourceReferences = new DeferredResourceReferenceList();
- }
+ _deferredResourceReferences ??= new DeferredResourceReferenceList();
if (_deferredResourceReferences.Get(resourceKey) is { } existingDeferredResourceReference
&& existingDeferredResourceReference.Dictionary == this)
@@ -1749,14 +1746,7 @@ private object FetchResource(
}
else
{
- if (_ownerApps != null)
- {
- deferredResourceReference = new DeferredAppResourceReference(this, resourceKey);
- }
- else
- {
- deferredResourceReference = new DeferredResourceReference(this, resourceKey);
- }
+ deferredResourceReference = _ownerApps is not null ? new DeferredAppResourceReference(this, resourceKey) : new DeferredResourceReference(this, resourceKey);
_deferredResourceReferences.AddOrSet(deferredResourceReference);
}
@@ -1781,10 +1771,29 @@ private object FetchResource(
///
private void ValidateDeferredResourceReferences(object resourceKey)
{
- if (_deferredResourceReferences != null)
+ if (_deferredResourceReferences is null)
+ {
+ return;
+ }
+
+ if (resourceKey is null)
+ {
+ foreach (DeferredResourceReference deferredResourceReference in _deferredResourceReferences)
+ {
+ Inflate(deferredResourceReference);
+ }
+ }
+ else
{
DeferredResourceReference deferredResourceReference = _deferredResourceReferences.Get(resourceKey);
+ Inflate(deferredResourceReference);
+ }
+
+ return;
+
+ void Inflate(DeferredResourceReference deferredResourceReference)
+ {
if (deferredResourceReference is not null)
{
// This will inflate the deferred reference, causing it
@@ -2504,9 +2513,9 @@ private enum PrivateFlags : byte
///
/// This wrapper class exists so SourceUriTypeConverterMarkupExtension can pass
- /// a more complete Uri to help resolve to the correct assembly, while also passing
+ /// a more complete Uri to help resolve to the correct assembly, while also passing
/// the original Uri so that ResourceDictionary.Source still returns the original value.
- ///
+ ///
internal class ResourceDictionarySourceUriWrapper : Uri
{
public ResourceDictionarySourceUriWrapper(Uri originalUri, Uri versionedUri) : base(originalUri.OriginalString, UriKind.RelativeOrAbsolute)
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceReferenceExpression.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceReferenceExpression.cs
index 7ccb5555d60..24804f3dc2f 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceReferenceExpression.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceReferenceExpression.cs
@@ -278,7 +278,10 @@ private void InvalidateCacheValue()
}
}
- deferredResourceReference.RemoveFromDictionary();
+ // This will inflate the deferred reference, causing it
+ // to be removed from the list. The list may also be
+ // purged of dead references.
+ deferredResourceReference.GetValue(BaseValueSourceInternal.Unknown);
}
StopListeningForFreezableChanges(resource);
@@ -341,8 +344,8 @@ private void InvalidateMentorCache()
internal void InvalidateExpressionValue(object sender, EventArgs e)
{
// VS has a scenario where a TreeWalk invalidates all reference expressions on a DependencyObject.
- // If there is a dependency between RRE's,
- // invalidating one RRE could cause _targetObject to be null on the other RRE. Hence this check.
+ // If there is a dependency between RRE's,
+ // invalidating one RRE could cause _targetObject to be null on the other RRE. Hence this check.
if (_targetObject == null)
{
return;
@@ -404,7 +407,7 @@ private void ListenForFreezableChanges(object resource)
{
_weakContainerRRE = new ResourceReferenceExpressionWeakContainer(this);
}
-
+
// Hook up the event to the weak container to prevent memory leaks (Bug436021)
_weakContainerRRE.AddChangedHandler(resourceAsFreezable);
WriteInternalState(InternalState.IsListeningForFreezableChanges, true);
@@ -435,7 +438,7 @@ private void StopListeningForFreezableChanges(object resource)
}
}
- // It is possible that a freezable was unfrozen during the call to ListForFreezableChanges
+ // It is possible that a freezable was unfrozen during the call to ListForFreezableChanges
// but was frozen before the call to StopListeningForFreezableChanges
WriteInternalState(InternalState.IsListeningForFreezableChanges, false);
}
@@ -512,8 +515,8 @@ private enum InternalState : byte
#region ResourceReferenceExpressionWeakContainer
///
- /// ResourceReferenceExpressionWeakContainer handles the Freezable.Changed event
- /// without holding a strong reference to ResourceReferenceExpression.
+ /// ResourceReferenceExpressionWeakContainer handles the Freezable.Changed event
+ /// without holding a strong reference to ResourceReferenceExpression.
///
private class ResourceReferenceExpressionWeakContainer : WeakReference
{
@@ -542,7 +545,7 @@ public void AddChangedHandler(Freezable resource)
}
_resource = resource;
-
+
Debug.Assert(!_resource.IsFrozen);
_resource.Changed += new EventHandler(this.InvalidateTargetSubProperty);
}
@@ -558,7 +561,7 @@ public void RemoveChangedHandler()
private Freezable _resource;
}
- #endregion
+ #endregion
}
///
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/SystemResources.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/SystemResources.cs
index 4a6622b9d01..280eaa21168 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/SystemResources.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/SystemResources.cs
@@ -1412,7 +1412,7 @@ private static IntPtr SystemThemeFilterMessage(IntPtr hwnd, int msg, IntPtr wPar
}
SystemParameters.InvalidateWindowFrameThicknessProperties();
-
+
if(ThemeManager.IsFluentThemeEnabled)
{
ThemeManager.ApplySystemTheme();
@@ -1733,8 +1733,7 @@ internal override object GetValue(BaseValueSourceInternal valueSource)
// the dictionary else just retun the cached value
if (_dictionary != null)
{
- bool canCache;
- object value = _dictionary.GetValue(_keyOrValue, out canCache);
+ object value = _dictionary.GetValue(_keyOrValue, out bool canCache);
if (canCache)
{
// Note that we are replacing the _keyorValue field
@@ -1790,8 +1789,7 @@ internal override Type GetValueType()
{
// Take a peek at the element type of the ElementStartRecord
// within the ResourceDictionary's deferred content.
- bool found;
- return _dictionary.GetValueType(_keyOrValue, out found);
+ return _dictionary.GetValueType(_keyOrValue, out bool _);
}
else
{
@@ -1800,7 +1798,7 @@ internal override Type GetValueType()
}
// remove this DeferredResourceReference from its ResourceDictionary
- internal virtual void RemoveFromDictionary()
+ protected virtual void RemoveFromDictionary()
{
if (_dictionary != null)
{
@@ -1970,7 +1968,7 @@ internal override Type GetValueType()
}
// remove this DeferredResourceReference from its ResourceDictionary
- internal override void RemoveFromDictionary()
+ protected override void RemoveFromDictionary()
{
// DeferredThemeResourceReferences are never added to the dictionary's
// list of deferred references, so they don't need to be removed.
@@ -2034,11 +2032,11 @@ internal override bool IsUnset
#endregion Properties
}
- internal class DeferredResourceReferenceList
+ internal class DeferredResourceReferenceList : IEnumerable
{
private readonly object _syncRoot = new();
private readonly Dictionary