Skip to content

Commit ec3c74f

Browse files
committed
Fix Issue #189
Rolling back removal of DctionaryTheme class with additional documentation for its usage.
1 parent 4e9c310 commit ec3c74f

File tree

6 files changed

+168
-38
lines changed

6 files changed

+168
-38
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ to also theme standard elements, such as, button and textblock etc.
134134

135135

136136
- 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)
137+
- [#189 Removal of DictionaryTheme breaks my application](https://github.com/Dirkster99/AvalonDock/issues/189) (thanx to [hamohn](https://github.com/hamohn))
137138

138139
## Fixes & Features added in Version 4.3
139140

source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs

+29-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/************************************************************************
1+
/************************************************************************
22
AvalonDock
33
44
Copyright (C) 2007-2013 Xceed Software Inc.
@@ -36,7 +36,7 @@ namespace AvalonDock.Controls
3636
public abstract class LayoutFloatingWindowControl : Window, ILayoutControl
3737
{
3838
#region fields
39-
39+
private ResourceDictionary currentThemeResourceDictionary; // = null
4040
private bool _isInternalChange; //false
4141
private readonly ILayoutElement _model;
4242
private bool _attachDrag = false;
@@ -246,22 +246,40 @@ public double ContentMinWidth
246246
#endregion Properties
247247

248248
#region Internal Methods
249-
249+
/// <summary>Is Invoked when AvalonDock's WPF Theme changes via the <see cref="DockingManager.OnThemeChanged()"/> method.</summary>
250+
/// <param name="oldTheme"></param>
250251
internal virtual void UpdateThemeResources(Theme oldTheme = null)
251252
{
252-
if (oldTheme != null)
253+
if (oldTheme != null) // Remove the old theme if present
253254
{
254-
var resourceDictionaryToRemove =
255-
Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
256-
if (resourceDictionaryToRemove != null)
257-
Resources.MergedDictionaries.Remove(
258-
resourceDictionaryToRemove);
255+
if (oldTheme is DictionaryTheme)
256+
{
257+
if (currentThemeResourceDictionary != null)
258+
{
259+
Resources.MergedDictionaries.Remove(currentThemeResourceDictionary);
260+
currentThemeResourceDictionary = null;
261+
}
262+
}
263+
else
264+
{
265+
var resourceDictionaryToRemove =
266+
Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
267+
if (resourceDictionaryToRemove != null)
268+
Resources.MergedDictionaries.Remove(
269+
resourceDictionaryToRemove);
270+
}
259271
}
260272

273+
// Implicit parameter to this method is the new theme already set here
261274
var manager = _model.Root?.Manager;
262275
if (manager?.Theme == null) return;
263-
264-
Resources.MergedDictionaries.Add(new ResourceDictionary { Source = manager.Theme.GetResourceUri() });
276+
if (manager.Theme is DictionaryTheme dictionaryTheme)
277+
{
278+
currentThemeResourceDictionary = dictionaryTheme.ThemeResourceDictionary;
279+
Resources.MergedDictionaries.Add(currentThemeResourceDictionary);
280+
}
281+
else
282+
Resources.MergedDictionaries.Add(new ResourceDictionary { Source = manager.Theme.GetResourceUri() });
265283
}
266284

267285
internal void AttachDrag(bool onActivated = true)

source/Components/AvalonDock/Controls/NavigatorWindow.cs

+26-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/************************************************************************
1+
/************************************************************************
22
AvalonDock
33
44
Copyright (C) 2007-2013 Xceed Software Inc.
@@ -28,6 +28,7 @@ namespace AvalonDock.Controls
2828
public class NavigatorWindow : Window
2929
{
3030
#region fields
31+
private ResourceDictionary currentThemeResourceDictionary; // = null
3132

3233
private const string PART_AnchorableListBox = "PART_AnchorableListBox";
3334
private const string PART_DocumentListBox = "PART_DocumentListBox";
@@ -286,17 +287,36 @@ protected override void OnPreviewKeyUp(System.Windows.Input.KeyEventArgs e)
286287
/// <param name="value">The new value for the property.</param>
287288
protected void SetDocuments(LayoutDocumentItem[] value) => SetValue(DocumentsPropertyKey, value);
288289

290+
/// <summary>Is Invoked when AvalonDock's WPF Theme changes via the <see cref="DockingManager.OnThemeChanged()"/> method.</summary>
291+
/// <param name="oldTheme"></param>
289292
internal void UpdateThemeResources(Theme oldTheme = null)
290293
{
291-
if (oldTheme != null)
294+
if (oldTheme != null) // Remove the old theme if present
292295
{
293-
var resourceDictionaryToRemove = Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
294-
if (resourceDictionaryToRemove != null) Resources.MergedDictionaries.Remove(resourceDictionaryToRemove);
296+
if (oldTheme is DictionaryTheme)
297+
{
298+
if (currentThemeResourceDictionary != null)
299+
{
300+
Resources.MergedDictionaries.Remove(currentThemeResourceDictionary);
301+
currentThemeResourceDictionary = null;
302+
}
303+
}
304+
else
305+
{
306+
var resourceDictionaryToRemove = Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
307+
if (resourceDictionaryToRemove != null) Resources.MergedDictionaries.Remove(resourceDictionaryToRemove);
308+
}
295309
}
296310

311+
// Implicit parameter to this method is the new theme already set here
297312
if (_manager.Theme == null) return;
298-
299-
Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = _manager.Theme.GetResourceUri() });
313+
if (_manager.Theme is DictionaryTheme dictionaryTheme)
314+
{
315+
currentThemeResourceDictionary = dictionaryTheme.ThemeResourceDictionary;
316+
Resources.MergedDictionaries.Add(currentThemeResourceDictionary);
317+
}
318+
else
319+
Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = _manager.Theme.GetResourceUri() });
300320
}
301321

302322
internal void SelectNextDocument()

source/Components/AvalonDock/Controls/OverlayWindow.cs

+31-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/************************************************************************
1+
/************************************************************************
22
AvalonDock
33
44
Copyright (C) 2007-2013 Xceed Software Inc.
@@ -25,6 +25,7 @@ namespace AvalonDock.Controls
2525
public class OverlayWindow : Window, IOverlayWindow
2626
{
2727
#region fields
28+
private ResourceDictionary currentThemeResourceDictionary; // = null
2829

2930
private Canvas _mainCanvasPanel;
3031
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)
169170
#endregion Overrides
170171

171172
#region Internal Methods
172-
173+
/// <summary>Is Invoked when AvalonDock's WPF Theme changes via the <see cref="DockingManager.OnThemeChanged()"/> method.</summary>
174+
/// <param name="oldTheme"></param>
173175
internal void UpdateThemeResources(Theme oldTheme = null)
174176
{
175-
if (oldTheme != null)
177+
if (oldTheme != null) // Remove the old theme if present
176178
{
177-
var resourceDictionaryToRemove =
178-
Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
179-
if (resourceDictionaryToRemove != null)
180-
Resources.MergedDictionaries.Remove(
181-
resourceDictionaryToRemove);
179+
if (oldTheme is DictionaryTheme)
180+
{
181+
if (currentThemeResourceDictionary != null)
182+
{
183+
Resources.MergedDictionaries.Remove(currentThemeResourceDictionary);
184+
currentThemeResourceDictionary = null;
185+
}
186+
}
187+
else
188+
{
189+
var resourceDictionaryToRemove =
190+
Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
191+
if (resourceDictionaryToRemove != null)
192+
Resources.MergedDictionaries.Remove(
193+
resourceDictionaryToRemove);
194+
}
182195
}
183196

184-
if (_host.Manager.Theme != null)
197+
if (_host.Manager.Theme != null) // Implicit parameter to this method is the new theme already set here
185198
{
186-
Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = _host.Manager.Theme.GetResourceUri() });
199+
if (_host.Manager.Theme is DictionaryTheme theme)
200+
{
201+
currentThemeResourceDictionary = theme.ThemeResourceDictionary;
202+
Resources.MergedDictionaries.Add(currentThemeResourceDictionary);
203+
}
204+
else
205+
{
206+
Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = _host.Manager.Theme.GetResourceUri() });
207+
}
187208
}
188209
}
189210

source/Components/AvalonDock/DockingManager.cs

+31-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/************************************************************************
1+
/************************************************************************
22
AvalonDock
33
44
Copyright (C) 2007-2013 Xceed Software Inc.
@@ -42,6 +42,9 @@ namespace AvalonDock
4242
public class DockingManager : Control, IOverlayWindowHost//, ILogicalChildrenContainer
4343
{
4444
#region fields
45+
// ShortCut to current AvalonDock theme if OnThemeChanged() is invoked with DictionaryTheme instance
46+
// in e.OldValue and e.NewValue of the passed event
47+
private ResourceDictionary currentThemeResourceDictionary;
4548

4649
private AutoHideWindowManager _autoHideWindowManager;
4750
private FrameworkElement _autohideArea;
@@ -1029,24 +1032,41 @@ protected virtual void OnThemeChanged(DependencyPropertyChangedEventArgs e)
10291032
{
10301033
var oldTheme = e.OldValue as Theme;
10311034
var resources = Resources;
1032-
if (oldTheme != null)
1035+
if (oldTheme != null) // remove old theme from resource dictionary if present
10331036
{
1034-
var resourceDictionaryToRemove =
1035-
resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
1036-
if (resourceDictionaryToRemove != null)
1037-
resources.MergedDictionaries.Remove(
1038-
resourceDictionaryToRemove);
1037+
if (oldTheme is DictionaryTheme) // We are using AvalonDock's own DictionaryTheme class
1038+
{
1039+
if (currentThemeResourceDictionary != null)
1040+
{
1041+
resources.MergedDictionaries.Remove(currentThemeResourceDictionary);
1042+
currentThemeResourceDictionary = null;
1043+
}
1044+
}
1045+
else // We are using standard ResourceDictionaries
1046+
{ // Lockup the old theme and remove it from resource dictionary
1047+
var resourceDictionaryToRemove =
1048+
resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri());
1049+
if (resourceDictionaryToRemove != null)
1050+
resources.MergedDictionaries.Remove(
1051+
resourceDictionaryToRemove);
1052+
}
10391053
}
10401054

1041-
if (e.NewValue as Theme != null)
1055+
if (e.NewValue as Theme != null) // Add new theme into resource dictionary if present
10421056
{
1043-
resources.MergedDictionaries.Add(new ResourceDictionary { Source = (e.NewValue as Theme).GetResourceUri() });
1057+
if (e.NewValue as Theme is DictionaryTheme theme)
1058+
{
1059+
currentThemeResourceDictionary = theme.ThemeResourceDictionary;
1060+
resources.MergedDictionaries.Add(currentThemeResourceDictionary);
1061+
}
1062+
else // We are using standard ResourceDictionaries -> Add new theme resource
1063+
resources.MergedDictionaries.Add(new ResourceDictionary { Source = (e.NewValue as Theme).GetResourceUri() });
10441064
}
10451065

1046-
foreach (var fwc in _fwList)
1066+
foreach (var fwc in _fwList) // Update theme resources in floating window controls
10471067
fwc.UpdateThemeResources(oldTheme);
10481068

1049-
_navigatorWindow?.UpdateThemeResources();
1069+
_navigatorWindow?.UpdateThemeResources(); // Update theme resources in related AvalonDock controls
10501070
_overlayWindow?.UpdateThemeResources();
10511071
}
10521072

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/************************************************************************
2+
AvalonDock
3+
4+
Copyright (C) 2007-2013 Xceed Software Inc.
5+
6+
This program is provided to you under the terms of the Microsoft Public
7+
License (Ms-PL) as published at https://opensource.org/licenses/MS-PL
8+
************************************************************************/
9+
10+
using System;
11+
using System.Windows;
12+
13+
namespace AvalonDock.Themes
14+
{
15+
/// <summary>Defines a base class to implement a method for storing the current AvalonDock theme
16+
/// that provides a XAML Uri pointing to a <see cref="ResourceDictionary"/>.
17+
///
18+
/// This class can be used to create customized themes by loading a <see cref="ResourceDictionary"/>
19+
/// from an existing theme (by using theme.GetResourceUri()), and then replacing some key colors
20+
/// (typically the "Accent" colors).
21+
///
22+
/// See Issue https://github.com/Dirkster99/AvalonDock/issues/189 for more details.</summary>
23+
public abstract class DictionaryTheme : Theme
24+
{
25+
#region Constructors
26+
/// <summary>Class constructor</summary>
27+
public DictionaryTheme()
28+
{
29+
}
30+
31+
/// <summary>Class constructor from theme specific resource dictionary.</summary>
32+
/// <param name="themeResourceDictionary"></param>
33+
public DictionaryTheme(ResourceDictionary themeResourceDictionary)
34+
{
35+
this.ThemeResourceDictionary = themeResourceDictionary;
36+
}
37+
38+
#endregion Constructors
39+
40+
/// <summary>Gets the resource dictionary that is associated with this AvalonDock theme.</summary>
41+
public ResourceDictionary ThemeResourceDictionary { get; private set; }
42+
43+
/// <summary>Gets the <see cref="Uri"/> of the XAML that contains the definition for this AvalonDock theme.</summary>
44+
/// <returns><see cref="Uri"/> of the XAML that contains the definition for this custom AvalonDock theme</returns>
45+
public override Uri GetResourceUri()
46+
{
47+
return null;
48+
}
49+
}
50+
}

0 commit comments

Comments
 (0)