- xplorerbar_demo.zip
- XPlorerBar_demo
- ZonaTools.XPlorerBar.DemoApp.exe
- ZonaTools.XPlorerBar.dll
- ZonaTools.XPlorerBar.Documentation.chm
- xplorerbar_src.zip
- XPlorerBar_src
- XPlorerBar.DemoApp.sln
- XPlorerBar.DemoApp.suo
- XPlorerBar.DemoApp
- App.xaml
- App.xaml.cs
- Converters
- Extra_BindingMode
- Extra_ThemeManagement
- Images
- codeproject120x60.gif
- Computer16.png
- Copy16.png
- CreateFolder16.png
- Delete16.png
- MailFile16.png
- Move16.png
- MusicOnLine16.png
- MyComputer16.png
- MyDocuments16.png
- MyMusic32.png
- MyNetwork16.png
- MyPictures16.png
- MyPictures32.png
- MyPictures48.png
- NetworkFavorites16.png
- OrderPictures16.png
- PlayAll16.png
- PrintPictures16.png
- PublishFolder16.png
- Rename16.png
- SharedMusic16.png
- ShareFolder16.png
- SlideShow16.png
- MainWindow.xaml
- MainWindow.xaml.cs
- Properties
- Resources
- Images
- Folder16.png
- MyComputer16.png
- NetworkPlaces16.png
- PicturePrint16.png
- PictureTasks32.png
- PictureTasksMono48.png
- PrintsOnline16.png
- SlideShow16.png
- Skins
- XPlorerBar.DemoApp.csproj
- XPlorerBar.Documentation
- Help
- Documentation.chm
- LastBuild.log
- XPlorerBarDocumentationProject.shfb
- XPlorerBar.Library
|
#region [ Copyright © 2008, Zona-Tools, all rights reserved. ]
/*
*
This source code is licensed under the Code Project Open License (CPOL).
Check out http://www.codeproject.com/info/cpol10.aspx for further details.
*
*/
#endregion
#region [ Using namespaces ]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
#endregion
namespace ZonaTools.XPlorerBar
{
#region [ Theme definition structure ]
/// <summary>
/// Represents a theme with its name and the path to its resource dictionary.
/// </summary>
public struct Theme
{
/// <summary>
/// Name of the theme.
/// </summary>
public string Name;
/// <summary>
/// Path of the theme resource dictionary.
/// </summary>
public string DictionaryPath;
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="name">Name of the theme.</param>
/// <param name="dictionaryPath">Path of the theme resource dictionary.</param>
public Theme(string name, string dictionaryPath)
{
Name = name;
DictionaryPath = dictionaryPath;
}
}
#endregion
#region [ Theme names enumeration ]
/// <summary>
/// Specifies the names of the most common themes.
/// </summary>
public enum Themes
{
/// <summary>
/// Name used to unload the themes of an element.
/// </summary>
Default,
/// <summary>
/// Name of the Aero.NormalColor theme.
/// </summary>
Aero,
/// <summary>
/// Name of the Classic theme.
/// </summary>
Classic,
/// <summary>
/// Name of the Luna.NormalColor theme.
/// </summary>
LunaBlue,
/// <summary>
/// Name of the Luna.Homestead theme.
/// </summary>
LunaOliveGreen,
/// <summary>
/// Name of the Luna.Metallic theme.
/// </summary>
LunaSilver,
/// <summary>
/// Name of the Royale.NormalColor theme.
/// </summary>
Royale,
/// <summary>
/// Name of the Zune.NormalColor theme.
/// </summary>
Zune,
/// <summary>
/// Name of the Blend theme.
/// </summary>
Blend
};
#endregion
/// <summary>
/// Manages the themes used by any <c>FrameworkElement</c>.
/// </summary>
public static class ThemeManager
{
#region [ String definitions ]
private const string Lang_Caption =
"Theme Management";
private const string Lang_ChangeThemeToPb =
"Unable to change the current theme because the '{0}' theme is not registered for the '{1}' objects.";
private const string Lang_RegisterThemePb =
"Unable to register the '{0}' theme for the '{1}' objects.";
#endregion
#region [ Fields ]
/// <summary>
/// Represents the collection of all the registered themes.
/// </summary>
/// <remarks>
/// The key of this dictionary represents the name used to register a theme.
/// </remarks>
private static Dictionary<string, ResourceDictionary>
_registeredDictionaries = new Dictionary<string, ResourceDictionary>();
#endregion
#region [ Dependency properties ]
#region Theme attached property
//===========================================================================
/// <summary>
/// Identifies the <c>Theme</c> attached property.
/// </summary>
/// <remarks>The default value is <c>Default</c>.</remarks>
//===========================================================================
public static readonly DependencyProperty ThemeProperty =
DependencyProperty.RegisterAttached("Theme",
typeof(string), typeof(ThemeManager),
new FrameworkPropertyMetadata(Themes.Default.ToString(),
FrameworkPropertyMetadataOptions.None,
new PropertyChangedCallback(OnThemeChanged)));
/// <summary>
/// Gets the value of the <c>Theme</c> attached property for a
/// specified <c>FrameworkElement</c>.
/// </summary>
[Category(XPlorerBar.CATEGORYNAME), AttachedPropertyBrowsableForType(typeof(FrameworkElement))]
public static string GetTheme(DependencyObject d)
{
if (d == null)
throw new ArgumentNullException("d");
return (string)d.GetValue(ThemeProperty);
}
/// <summary>
/// Sets the value of the <c>Theme</c> attached property to a
/// specified <c>FrameworkElement</c>.
/// </summary>
public static void SetTheme(DependencyObject d, string value)
{
if (d == null)
throw new ArgumentNullException("d");
d.SetValue(ThemeProperty, value);
}
/// <summary>
/// Invoked whenever the <c>Theme</c> attached property value has
/// been updated.
/// </summary>
/// <param name="d">The <c>DependencyObject</c> on which the property has
/// changed value.</param>
/// <param name="e">Event data that is issued by any event that tracks changes
/// to the effective value of this property.</param>
private static void OnThemeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//Gets the element on which apply the new theme
FrameworkElement element = d as FrameworkElement;
//Makes sure the arguments are valid
if (element == null)
throw new ArgumentNullException("d");
if (e == null)
throw new ArgumentNullException("e");
//-------------------------------------------------------------
//Removes the current theme dictionary from element's resources
//-------------------------------------------------------------
//Gets the name of the current theme
string curThemeName = e.OldValue as string;
//If the current theme is the default theme, there's nothing to remove
if (!curThemeName.Equals(Themes.Default.ToString()))
{
//Gets the registered name of the current theme
string curRegisteredThemeName =
GetRegistrationName(curThemeName, element.GetType());
//If the current theme is registered
if (_registeredDictionaries.ContainsKey(curRegisteredThemeName))
{
//Gets the resource dictionary of the current theme
ResourceDictionary curThemeDictionary =
_registeredDictionaries[curRegisteredThemeName];
//and removes it
element.Resources.MergedDictionaries.Remove(curThemeDictionary);
}
}
//----------------------------------------------------
//Adds the new theme dictionary to element's resources
//----------------------------------------------------
//Gets the name of the new theme
string newThemeName = e.NewValue as string;
//If the new theme is the default theme, there's nothing to add
if (!newThemeName.Equals(Themes.Default.ToString()))
{
//Gets the registered name of the new theme
string newRegisteredThemeName =
GetRegistrationName(newThemeName, element.GetType());
//If the new theme is not registered
if (!_registeredDictionaries.ContainsKey(newRegisteredThemeName))
{
//Displays an error message
MessageBox.Show(
string.Format(Lang_ChangeThemeToPb, newThemeName, element.GetType().ToString()),
Lang_Caption, MessageBoxButton.OK, MessageBoxImage.Warning);
}
else
{
//Gets the resource dictionary of the new theme
ResourceDictionary newThemeDictionary =
_registeredDictionaries[newRegisteredThemeName];
//and applies it to the source element
element.Resources.MergedDictionaries.Add(newThemeDictionary);
}
}
}
#endregion
#endregion
#region [ Registers a new theme ]
//===========================================================================
/// <summary>
/// Registers a new theme with a specified name and a specified <c>Uri</c>.
/// </summary>
/// <param name="theme">Theme to register.</param>
/// <param name="ownerType">The owner type that is registering the theme.
/// </param>
//===========================================================================
public static void RegisterTheme(Theme theme, Type ownerType)
{
//Makes sure the arguments are valid
if ((theme.Name == null) || (theme.DictionaryPath == null))
throw new ArgumentNullException("theme");
if (ownerType == null)
throw new ArgumentNullException("ownerType");
//Gets the registration name
string registrationName =
GetRegistrationName(theme.Name, ownerType);
//Checks that the new theme is not the default theme and
//that it is not already registered
if (theme.Name.Equals(Themes.Default.ToString()) ||
_registeredDictionaries.ContainsKey(registrationName))
return;
try
{
//Creates the Uri of the specified theme
Uri themeUri = new Uri(theme.DictionaryPath, UriKind.Relative);
//Registers the new theme
_registeredDictionaries[registrationName] =
Application.LoadComponent(themeUri) as ResourceDictionary;
}
catch
{
//Dislays an error message
MessageBox.Show(
string.Format(Lang_RegisterThemePb, theme.Name, ownerType.ToString()),
Lang_Caption, MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
//===========================================================================
/// <summary>
/// Gets the name used for the registration of the specified theme.
/// </summary>
/// <param name="themeName">Name of the theme to register.</param>
/// <param name="ownerType">The owner type that is registering the theme.
/// </param>
/// <returns>Name used for the registration of the specified theme.</returns>
//===========================================================================
private static string GetRegistrationName(string themeName, Type ownerType)
{
//Sets the registration name (Type name;theme name)
string registrationName =
string.Format("{0};{1}", ownerType.ToString(), themeName);
return registrationName;
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I have been developing and managing projects for real-time embedded softwares for eight years. Then, I moved from Paris to the south of France and began to lead a team who was developping Java applications.
My main occupation right now is to continue my journey in the WPF world.
You can check out my blog
here. [
^]