Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix an issue that ThemeHelper isn't enabled after reloading. #51

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 77 additions & 3 deletions source/MetroRadiance/UI/Controls/ThemeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ namespace MetroRadiance.UI.Controls
public static class ThemeHelper
{
private static readonly Dictionary<FrameworkElement, IDisposable> registeredElements = new Dictionary<FrameworkElement, IDisposable>();


private static void AddResources(FrameworkElement element)
=> registeredElements[element] = ThemeService.Current.Register(element.Resources);

private static void RemoveResources(FrameworkElement element)
{
IDisposable disposable;
Expand Down Expand Up @@ -58,8 +61,7 @@ private static void HasThemeResourcesChangedCallback(DependencyObject d, Depende
else if (!oldValue && newValue)
{
// false -> true
registeredElements[element] = ThemeService.Current.Register(element.Resources);
element.Unloaded += ElementUnloadedCallback;
FrameworkElementLoadedWeakEventManager.AddHandler(element, ElementLoadedCallback);
}
};

Expand All @@ -79,6 +81,13 @@ private static void HasThemeResourcesChangedCallback(DependencyObject d, Depende
}
}

private static void ElementLoadedCallback(object sender, RoutedEventArgs e)
{
var element = (FrameworkElement)sender;
AddResources(element);
element.Unloaded += ElementUnloadedCallback;
}

private static void ElementUnloadedCallback(object sender, RoutedEventArgs e)
{
var element = (FrameworkElement)sender;
Expand All @@ -87,5 +96,70 @@ private static void ElementUnloadedCallback(object sender, RoutedEventArgs e)
}

#endregion

private sealed class FrameworkElementLoadedWeakEventManager : WeakEventManager
{
/// <summary>
/// Add a handler for the given source's event.
/// </summary>
public static void AddHandler(FrameworkElement source, EventHandler<RoutedEventArgs> handler)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (handler == null) throw new ArgumentNullException(nameof(handler));

CurrentManager.ProtectedAddHandler(source, handler);
}

/// <summary>
/// Remove a handler for the given source's event.
/// </summary>
public static void RemoveHandler(FrameworkElement source, EventHandler<RoutedEventArgs> handler)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (handler == null) throw new ArgumentNullException(nameof(handler));

CurrentManager.ProtectedRemoveHandler(source, handler);
}

private static FrameworkElementLoadedWeakEventManager CurrentManager
{
get
{
var managerType = typeof(FrameworkElementLoadedWeakEventManager);
var manager = (FrameworkElementLoadedWeakEventManager)GetCurrentManager(managerType);
if (manager == null)
{
manager = new FrameworkElementLoadedWeakEventManager();
SetCurrentManager(managerType, manager);
}
return manager;
}
}

private FrameworkElementLoadedWeakEventManager()
{ }

protected override ListenerList NewListenerList()
{
return new ListenerList<RoutedEventArgs>();
}

protected override void StartListening(object source)
{
var element = (FrameworkElement)source;
element.Loaded += this.OnElementLoaded;
}

protected override void StopListening(object source)
{
var element = (FrameworkElement)source;
element.Loaded -= this.OnElementLoaded;
}

private void OnElementLoaded(object sender, RoutedEventArgs e)
{
this.DeliverEvent(sender, e);
}
}
}
}