Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

XPlorerBar: A WPF Windows XP Style Explorer Bar Control

, 9 Dec 2008 CPOL
A fully customizable WPF implementation of the left side pane that was introduced in Windows XP's Explorer.
XPlorerBar_demo.zip
XPlorerBar_demo
ZonaTools.XPlorerBar.DemoApp.exe
ZonaTools.XPlorerBar.dll
ZonaTools.XPlorerBar.Documentation.chm
XPlorerBar_src.zip
XPlorerBar_src
XPlorerBar.DemoApp
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
Properties
Settings.settings
Resources
Images
Folder16.png
MyComputer16.png
NetworkPlaces16.png
PicturePrint16.png
PictureTasks32.png
PictureTasksMono48.png
PrintsOnline16.png
SlideShow16.png
Skins
XPlorerBar.DemoApp.suo
XPlorerBar.Documentation
Help
Documentation.chm
LastBuild.log
XPlorerBarDocumentationProject.shfb
XPlorerBar.Library
Converters
Documents
ReleaseHistory.pdf
TestPlan.pdf
Implementation
Properties
Settings.settings
Themes
#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.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Xml;

#endregion


namespace ZonaTools.XPlorerBar
{
    /// <summary>
    /// Represents a control used to display grouped command items (as the
    /// task bar that was introduced in Windows XP's explorer).
    /// </summary>
    public class XPlorerBar : ItemsControl
    {
        #region [       Constants       ]

        /// <summary>
        /// Name of the XPlorerSection's properties category in the property grid
        /// of the control.
        /// </summary>
        internal const string CATEGORYNAME = "Zona-Tools Properties";

        #endregion


        #region [       Built-in themes declarations       ]

        /// <summary>
        /// Windows Vista Aero theme.
        /// </summary>
        public static Theme AeroNormalColorTheme = new Theme(
            Themes.Aero.ToString(),
            "/ZonaTools.XPlorerBar;component/Themes/Aero.NormalColor.xaml");
        /// <summary>
        /// Windows NT Classic theme.
        /// </summary>
        public static Theme ClassicTheme = new Theme(
            Themes.Classic.ToString(),
            "/ZonaTools.XPlorerBar;component/Themes/Classic.xaml");
        /// <summary>
        /// Windows XP Luna olive green theme.
        /// </summary>
        public static Theme LunaHomesteadTheme = new Theme(
            Themes.LunaOliveGreen.ToString(),
            "/ZonaTools.XPlorerBar;component/Themes/Luna.Homestead.xaml");
        /// <summary>
        /// Windows XP Luna silver theme.
        /// </summary>
        public static Theme LunaMetallicTheme = new Theme(
            Themes.LunaSilver.ToString(),
            "/ZonaTools.XPlorerBar;component/Themes/Luna.Metallic.xaml");
        /// <summary>
        /// Windows XP Luna blue theme.
        /// </summary>
        public static Theme LunaNormalColorTheme = new Theme(
            Themes.LunaBlue.ToString(),
            "/ZonaTools.XPlorerBar;component/Themes/Luna.NormalColor.xaml");
        /// <summary>
        /// Windows XP Royale theme.
        /// </summary>
        public static Theme RoyaleNormalColorTheme = new Theme(
            Themes.Royale.ToString(),
            "/ZonaTools.XPlorerBar;component/Themes/Royale.NormalColor.xaml");
        /// <summary>
        /// Windows XP Zune theme.
        /// </summary>
        public static Theme ZuneNormalColorTheme = new Theme(
            Themes.Zune.ToString(),
            "/ZonaTools.XPlorerBar;component/Themes/Zune.NormalColor.xaml");
        /// <summary>
        /// Microsoft Blend theme.
        /// </summary>
        public static Theme BlendTheme = new Theme(
            Themes.Blend.ToString(),
            "ZonaTools.XPlorerBar;component/Themes/BlendDictionary.xaml");

        #endregion


        #region [       Constructor       ]

        //===========================================================================
        /// <summary>
        /// Static constructor used to override the dependency properties (if
        /// needed) and define the default style for the control.
        /// </summary>
        //===========================================================================
        static XPlorerBar()
        {
            //Provides a new default style for the XPlorerBar element
            DefaultStyleKeyProperty.OverrideMetadata(typeof(XPlorerBar), 
                new FrameworkPropertyMetadata(typeof(XPlorerBar)));
        }

        //===========================================================================
        /// <summary>
        /// Default constructor.
        /// </summary>
        //===========================================================================
        public XPlorerBar()
        {
            //Adds an event handler on the 'Expanded' event of an XPlorerSection
            this.AddHandler(XPlorerSection.ExpandedEvent, 
                new RoutedEventHandler(this.OnExpanderHasExpanded));

            //Registers the built-in themes for the XPlorerBar class
            ThemeManager.RegisterTheme(AeroNormalColorTheme, typeof(XPlorerBar));
            ThemeManager.RegisterTheme(ClassicTheme, typeof(XPlorerBar));
            ThemeManager.RegisterTheme(LunaHomesteadTheme, typeof(XPlorerBar));
            ThemeManager.RegisterTheme(LunaMetallicTheme, typeof(XPlorerBar));
            ThemeManager.RegisterTheme(LunaNormalColorTheme, typeof(XPlorerBar));
            ThemeManager.RegisterTheme(RoyaleNormalColorTheme, typeof(XPlorerBar));
            ThemeManager.RegisterTheme(ZuneNormalColorTheme, typeof(XPlorerBar));
            ThemeManager.RegisterTheme(BlendTheme, typeof(XPlorerBar));
        }

        #endregion


        #region [       Dependency properties       ]

        #region AllowMultipleExpands property

        //===========================================================================
        /// <summary>
        /// Gets or sets a value indicating whether multiple XPlorerSection can be
        /// expanded at the same time. This is a dependency property.
        /// </summary>
        /// <remarks>
        /// The default value is <c>true</c>.
        /// </remarks>
        //===========================================================================
        [Category(CATEGORYNAME), Browsable(true)]
        public bool AllowMultipleExpands
        {
            get { return (bool)GetValue(AllowMultipleExpandsProperty); }
            set { SetValue(AllowMultipleExpandsProperty, value); }
        }

        /// <summary>
        /// Identifies the <see cref="AllowMultipleExpands"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty AllowMultipleExpandsProperty =
            DependencyProperty.Register("AllowMultipleExpands",
            typeof(bool), typeof(XPlorerBar),
            new FrameworkPropertyMetadata(true, new PropertyChangedCallback(OnAllowMultipleExpandsChanged)));

        /// <summary>
        /// Invoked whenever the <c>AllowMultipleExpands</c> dependency property value
        /// has been updated.
        /// </summary>
        /// <param name="sender">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 OnAllowMultipleExpandsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            //Gets the XPlorerBar who sent the event
            XPlorerBar xpBar = (XPlorerBar)sender;
            //Gets the new value of the 'AllowMultipleExpands' DP
            bool newAllowMultipleExpands = (bool)e.NewValue;
            
            //If the new value is not 'Allow multiple expands'
            if (!newAllowMultipleExpands)
                //collapses every XPlorerSection except one
                xpBar.ManageSingleExpand(null);
        }

        #endregion

        #endregion


        #region [       Single/multiple expands management       ]

        //===========================================================================
        /// <summary>
        /// Invoked whenever the <c>XPlorerSection.IsExpanded</c> dependency property 
        /// value has been updated.
        /// </summary>
        /// <param name="sender">The object where the event handler is 
        /// attached.</param>
        /// <param name="args">The event data.</param>
        //===========================================================================
        private void OnExpanderHasExpanded(object sender, RoutedEventArgs args)
        {
            //Gets the XPlorerSection instance that has been expanded
            XPlorerSection exp = args.OriginalSource as XPlorerSection;

            //If multiple expands are not allowed, updates the 'IsExpanded' DP of
            //all the nested XPlorerSection instances
            if (!AllowMultipleExpands)
                ManageSingleExpand(exp);
        }


        //===========================================================================
        /// <summary>
        /// Updates the <c>IsExpanded</c> DP of all the nested XPlorerSection
        /// instances in order to have only one expanded XPlorerSection.
        /// </summary>
        /// <param name="xpSection">XPlorerSection instance that has been expanded.
        /// Null, if no XPlorerSection has been expanded.</param>
        /// <remarks>
        /// On intialization or when the <c>AllowMultipleExpands</c> DP has been
        /// updated, call this method with <c>null</c> as a parameter.
        /// </remarks>
        //===========================================================================
        private void ManageSingleExpand(XPlorerSection xpSection)
        {
            bool foundAnExpandedXPSection = false;

            //Loops the nested XPlorerSection
            for (int index = 0; index < this.Items.Count; index++)
            {
                //Gets the (index)th XPlorerSection
                XPlorerSection curSection = this.Items[index] as XPlorerSection;

                //Remark: curSection is null in binding mode => in binding mode,
                //the AllowMultipleExpands = False must not be active.
                if (curSection != null)
                {
                    //If the parameter is not null (i.e. xpSection is being expanded)
                    if (xpSection != null)
                    {
                        //All the other sections have to be collapsed
                        if (!curSection.Equals(xpSection))
                            curSection.IsExpanded = false;
                    }
                    else //i.e. Initialization or 'AllowMultipleExpands' DP is set to false
                    {
                        //if there is at least one expanded XPlorerSection
                        if (foundAnExpandedXPSection)
                            //Collapses the current XPlorerSection
                            curSection.IsExpanded = false;
                        else
                        {
                            //If the current XPlorerSection is expanded
                            if (curSection.IsExpanded)
                                //sets the 'foundAnExpandedXPSection' flag to true
                                foundAnExpandedXPSection = true;
                        }
                    }
                }
            }
        }

        #endregion


        #region [       Layout helpers       ]

        ////===========================================================================
        ///// <summary>
        ///// Determines if the specified item is (or is eligible to be) its own 
        ///// container.
        ///// </summary>
        ///// <param name="item">The item to check.</param>
        ///// <returns><c>true</c> if the item is (or is eligible to be) its own container; 
        ///// otherwise, <c>false.</c></returns>
        ////===========================================================================
        //protected override bool IsItemItsOwnContainerOverride(object item)
        //{
        //    return (item is XPlorerSection);
        //}


        ////===========================================================================
        ///// <summary>
        ///// Creates or identifies the element that is used to display the given item.
        ///// </summary>
        ///// <returns>The element that is used to display the given item.</returns>
        ////===========================================================================
        //protected override DependencyObject GetContainerForItemOverride()
        //{
        //    return new XPlorerSection();
        //}

        #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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Olivier Simon
Team Leader
France France
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. [^]

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 9 Dec 2008
Article Copyright 2008 by Olivier Simon
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid