diff --git a/README.md b/README.md
index b653144e..9cf05dc7 100644
--- a/README.md
+++ b/README.md
@@ -134,6 +134,7 @@ to also theme standard elements, such as, button and textblock etc.
- Removed the additional [ToolTip](https://github.com/Dirkster99/AvalonDock/commit/5554de5c4bfadc37f974ba29803dc792b54f00d0) and [ContextMenu](https://github.com/Dirkster99/AvalonDock/commit/103e1068bc9f5bae8fef275a0e785393b4115764) styles from the Generic.xaml in VS2013 [more details here](https://github.com/Dirkster99/AvalonDock/pull/170#issuecomment-674253874)
+- [#189 Removal of DictionaryTheme breaks my application](https://github.com/Dirkster99/AvalonDock/issues/189) (thanx to [hamohn](https://github.com/hamohn))
## Fixes & Features added in Version 4.3
diff --git a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs
index a1dffba6..0a36a813 100644
--- a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs
+++ b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs
@@ -1,4 +1,4 @@
-/************************************************************************
+/************************************************************************
AvalonDock
Copyright (C) 2007-2013 Xceed Software Inc.
@@ -36,7 +36,7 @@ namespace AvalonDock.Controls
public abstract class LayoutFloatingWindowControl : Window, ILayoutControl
{
#region fields
-
+ private ResourceDictionary currentThemeResourceDictionary; // = null
private bool _isInternalChange; //false
private readonly ILayoutElement _model;
private bool _attachDrag = false;
@@ -246,22 +246,40 @@ public double ContentMinWidth
#endregion Properties
#region Internal Methods
-
+ /// Is Invoked when AvalonDock's WPF Theme changes via the method.
+ ///
internal virtual void UpdateThemeResources(Theme oldTheme = null)
{
- if (oldTheme != null)
+ if (oldTheme != null) // Remove the old theme if present
{
- var resourceDictionaryToRemove =
- Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
- if (resourceDictionaryToRemove != null)
- Resources.MergedDictionaries.Remove(
- resourceDictionaryToRemove);
+ if (oldTheme is DictionaryTheme)
+ {
+ if (currentThemeResourceDictionary != null)
+ {
+ Resources.MergedDictionaries.Remove(currentThemeResourceDictionary);
+ currentThemeResourceDictionary = null;
+ }
+ }
+ else
+ {
+ var resourceDictionaryToRemove =
+ Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
+ if (resourceDictionaryToRemove != null)
+ Resources.MergedDictionaries.Remove(
+ resourceDictionaryToRemove);
+ }
}
+ // Implicit parameter to this method is the new theme already set here
var manager = _model.Root?.Manager;
if (manager?.Theme == null) return;
-
- Resources.MergedDictionaries.Add(new ResourceDictionary { Source = manager.Theme.GetResourceUri() });
+ if (manager.Theme is DictionaryTheme dictionaryTheme)
+ {
+ currentThemeResourceDictionary = dictionaryTheme.ThemeResourceDictionary;
+ Resources.MergedDictionaries.Add(currentThemeResourceDictionary);
+ }
+ else
+ Resources.MergedDictionaries.Add(new ResourceDictionary { Source = manager.Theme.GetResourceUri() });
}
internal void AttachDrag(bool onActivated = true)
diff --git a/source/Components/AvalonDock/Controls/NavigatorWindow.cs b/source/Components/AvalonDock/Controls/NavigatorWindow.cs
index 8c808a7d..f488d12f 100644
--- a/source/Components/AvalonDock/Controls/NavigatorWindow.cs
+++ b/source/Components/AvalonDock/Controls/NavigatorWindow.cs
@@ -1,4 +1,4 @@
-/************************************************************************
+/************************************************************************
AvalonDock
Copyright (C) 2007-2013 Xceed Software Inc.
@@ -28,6 +28,7 @@ namespace AvalonDock.Controls
public class NavigatorWindow : Window
{
#region fields
+ private ResourceDictionary currentThemeResourceDictionary; // = null
private const string PART_AnchorableListBox = "PART_AnchorableListBox";
private const string PART_DocumentListBox = "PART_DocumentListBox";
@@ -286,17 +287,36 @@ protected override void OnPreviewKeyUp(System.Windows.Input.KeyEventArgs e)
/// The new value for the property.
protected void SetDocuments(LayoutDocumentItem[] value) => SetValue(DocumentsPropertyKey, value);
+ /// Is Invoked when AvalonDock's WPF Theme changes via the method.
+ ///
internal void UpdateThemeResources(Theme oldTheme = null)
{
- if (oldTheme != null)
+ if (oldTheme != null) // Remove the old theme if present
{
- var resourceDictionaryToRemove = Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
- if (resourceDictionaryToRemove != null) Resources.MergedDictionaries.Remove(resourceDictionaryToRemove);
+ if (oldTheme is DictionaryTheme)
+ {
+ if (currentThemeResourceDictionary != null)
+ {
+ Resources.MergedDictionaries.Remove(currentThemeResourceDictionary);
+ currentThemeResourceDictionary = null;
+ }
+ }
+ else
+ {
+ var resourceDictionaryToRemove = Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
+ if (resourceDictionaryToRemove != null) Resources.MergedDictionaries.Remove(resourceDictionaryToRemove);
+ }
}
+ // Implicit parameter to this method is the new theme already set here
if (_manager.Theme == null) return;
-
- Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = _manager.Theme.GetResourceUri() });
+ if (_manager.Theme is DictionaryTheme dictionaryTheme)
+ {
+ currentThemeResourceDictionary = dictionaryTheme.ThemeResourceDictionary;
+ Resources.MergedDictionaries.Add(currentThemeResourceDictionary);
+ }
+ else
+ Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = _manager.Theme.GetResourceUri() });
}
internal void SelectNextDocument()
diff --git a/source/Components/AvalonDock/Controls/OverlayWindow.cs b/source/Components/AvalonDock/Controls/OverlayWindow.cs
index d5e64062..4ad7d5b4 100644
--- a/source/Components/AvalonDock/Controls/OverlayWindow.cs
+++ b/source/Components/AvalonDock/Controls/OverlayWindow.cs
@@ -1,4 +1,4 @@
-/************************************************************************
+/************************************************************************
AvalonDock
Copyright (C) 2007-2013 Xceed Software Inc.
@@ -25,6 +25,7 @@ namespace AvalonDock.Controls
public class OverlayWindow : Window, IOverlayWindow
{
#region fields
+ private ResourceDictionary currentThemeResourceDictionary; // = null
private Canvas _mainCanvasPanel;
private Grid _gridDockingManagerDropTargets; // Showing and activating 4 outer drop taget buttons over DockingManager
@@ -169,21 +170,41 @@ protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
#endregion Overrides
#region Internal Methods
-
+ /// Is Invoked when AvalonDock's WPF Theme changes via the method.
+ ///
internal void UpdateThemeResources(Theme oldTheme = null)
{
- if (oldTheme != null)
+ if (oldTheme != null) // Remove the old theme if present
{
- var resourceDictionaryToRemove =
- Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
- if (resourceDictionaryToRemove != null)
- Resources.MergedDictionaries.Remove(
- resourceDictionaryToRemove);
+ if (oldTheme is DictionaryTheme)
+ {
+ if (currentThemeResourceDictionary != null)
+ {
+ Resources.MergedDictionaries.Remove(currentThemeResourceDictionary);
+ currentThemeResourceDictionary = null;
+ }
+ }
+ else
+ {
+ var resourceDictionaryToRemove =
+ Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
+ if (resourceDictionaryToRemove != null)
+ Resources.MergedDictionaries.Remove(
+ resourceDictionaryToRemove);
+ }
}
- if (_host.Manager.Theme != null)
+ if (_host.Manager.Theme != null) // Implicit parameter to this method is the new theme already set here
{
- Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = _host.Manager.Theme.GetResourceUri() });
+ if (_host.Manager.Theme is DictionaryTheme theme)
+ {
+ currentThemeResourceDictionary = theme.ThemeResourceDictionary;
+ Resources.MergedDictionaries.Add(currentThemeResourceDictionary);
+ }
+ else
+ {
+ Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = _host.Manager.Theme.GetResourceUri() });
+ }
}
}
diff --git a/source/Components/AvalonDock/DockingManager.cs b/source/Components/AvalonDock/DockingManager.cs
index 3909e684..f42c91fd 100644
--- a/source/Components/AvalonDock/DockingManager.cs
+++ b/source/Components/AvalonDock/DockingManager.cs
@@ -1,4 +1,4 @@
-/************************************************************************
+/************************************************************************
AvalonDock
Copyright (C) 2007-2013 Xceed Software Inc.
@@ -42,6 +42,9 @@ namespace AvalonDock
public class DockingManager : Control, IOverlayWindowHost//, ILogicalChildrenContainer
{
#region fields
+ // ShortCut to current AvalonDock theme if OnThemeChanged() is invoked with DictionaryTheme instance
+ // in e.OldValue and e.NewValue of the passed event
+ private ResourceDictionary currentThemeResourceDictionary;
private AutoHideWindowManager _autoHideWindowManager;
private FrameworkElement _autohideArea;
@@ -1029,24 +1032,41 @@ protected virtual void OnThemeChanged(DependencyPropertyChangedEventArgs e)
{
var oldTheme = e.OldValue as Theme;
var resources = Resources;
- if (oldTheme != null)
+ if (oldTheme != null) // remove old theme from resource dictionary if present
{
- var resourceDictionaryToRemove =
- resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
- if (resourceDictionaryToRemove != null)
- resources.MergedDictionaries.Remove(
- resourceDictionaryToRemove);
+ if (oldTheme is DictionaryTheme) // We are using AvalonDock's own DictionaryTheme class
+ {
+ if (currentThemeResourceDictionary != null)
+ {
+ resources.MergedDictionaries.Remove(currentThemeResourceDictionary);
+ currentThemeResourceDictionary = null;
+ }
+ }
+ else // We are using standard ResourceDictionaries
+ { // Lockup the old theme and remove it from resource dictionary
+ var resourceDictionaryToRemove =
+ resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
+ if (resourceDictionaryToRemove != null)
+ resources.MergedDictionaries.Remove(
+ resourceDictionaryToRemove);
+ }
}
- if (e.NewValue as Theme != null)
+ if (e.NewValue as Theme != null) // Add new theme into resource dictionary if present
{
- resources.MergedDictionaries.Add(new ResourceDictionary { Source = (e.NewValue as Theme).GetResourceUri() });
+ if (e.NewValue as Theme is DictionaryTheme theme)
+ {
+ currentThemeResourceDictionary = theme.ThemeResourceDictionary;
+ resources.MergedDictionaries.Add(currentThemeResourceDictionary);
+ }
+ else // We are using standard ResourceDictionaries -> Add new theme resource
+ resources.MergedDictionaries.Add(new ResourceDictionary { Source = (e.NewValue as Theme).GetResourceUri() });
}
- foreach (var fwc in _fwList)
+ foreach (var fwc in _fwList) // Update theme resources in floating window controls
fwc.UpdateThemeResources(oldTheme);
- _navigatorWindow?.UpdateThemeResources();
+ _navigatorWindow?.UpdateThemeResources(); // Update theme resources in related AvalonDock controls
_overlayWindow?.UpdateThemeResources();
}
diff --git a/source/Components/AvalonDock/Themes/DictionaryTheme.cs b/source/Components/AvalonDock/Themes/DictionaryTheme.cs
new file mode 100644
index 00000000..fa8c5ac9
--- /dev/null
+++ b/source/Components/AvalonDock/Themes/DictionaryTheme.cs
@@ -0,0 +1,50 @@
+/************************************************************************
+ AvalonDock
+
+ Copyright (C) 2007-2013 Xceed Software Inc.
+
+ This program is provided to you under the terms of the Microsoft Public
+ License (Ms-PL) as published at https://opensource.org/licenses/MS-PL
+ ************************************************************************/
+
+using System;
+using System.Windows;
+
+namespace AvalonDock.Themes
+{
+ /// Defines a base class to implement a method for storing the current AvalonDock theme
+ /// that provides a XAML Uri pointing to a .
+ ///
+ /// This class can be used to create customized themes by loading a
+ /// from an existing theme (by using theme.GetResourceUri()), and then replacing some key colors
+ /// (typically the "Accent" colors).
+ ///
+ /// See Issue https://github.com/Dirkster99/AvalonDock/issues/189 for more details.
+ public abstract class DictionaryTheme : Theme
+ {
+ #region Constructors
+ /// Class constructor
+ public DictionaryTheme()
+ {
+ }
+
+ /// Class constructor from theme specific resource dictionary.
+ ///
+ public DictionaryTheme(ResourceDictionary themeResourceDictionary)
+ {
+ this.ThemeResourceDictionary = themeResourceDictionary;
+ }
+
+ #endregion Constructors
+
+ /// Gets the resource dictionary that is associated with this AvalonDock theme.
+ public ResourceDictionary ThemeResourceDictionary { get; private set; }
+
+ /// Gets the of the XAML that contains the definition for this AvalonDock theme.
+ /// of the XAML that contains the definition for this custom AvalonDock theme
+ public override Uri GetResourceUri()
+ {
+ return null;
+ }
+ }
+}