Click here to Skip to main content
15,886,519 members
Articles / Desktop Programming / WPF

XPlorerBar : Part 2 - Adding design-time support to the WPF explorer bar control

Rate me:
Please Sign up or sign in to vote.
4.98/5 (50 votes)
22 Dec 2008CPOL14 min read 96.1K   2.7K   109  
This library provides Visual Studio 2008 design-time support to customize WPF XPlorerBar features.
#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.Windows;
using System.Windows.Controls;
using Microsoft.Windows.Design.Interaction;
using Microsoft.Windows.Design.Model;

#endregion


namespace ZonaTools.XPlorerBar.VisualStudio.Design
{
    /// <summary>
    /// Provides a context menu on any selected XPlorerSection object.
    /// </summary>
    internal class XPlorerSectionContextMenuProvider : PrimarySelectionContextMenuProvider
    {
        #region [       Constants       ]

        //Name of the parent's property which enables the nested items retrieval.
        const string parentChildrenRetrievalProperty = "Items";

        #endregion


        #region [       Fields       ]

        //'Expand/Collapse' menu item
        private MenuAction _expandCollapseMenuAction = new MenuAction("Expand");

        //'Manage section' sub-menu items
        private MenuAction _moveUpMenuAction = new MenuAction("Move up");
        private MenuAction _moveDownMenuAction = new MenuAction("Move Down");
        private MenuAction _IsPrimaryMenuAction = new MenuAction("IsPrimary");

        //'Manage items' sub-menu item
        private MenuAction _addXPlorerItemMenuAction = new MenuAction("Add an XPlorerItem");

        #endregion


        #region [       Constructor       ]

        //===========================================================================
        /// <summary>
        /// Default constructor.
        /// </summary>
        //===========================================================================
        public XPlorerSectionContextMenuProvider()
        {
            #region 'Expand/Collapse' menu

            //Adds handler on the 'Execute' event
            _expandCollapseMenuAction.Execute += 
                new EventHandler<MenuActionEventArgs>(_expandCollapseMenuAction_Execute);

            //Adds the menu to the context menu provider
            this.Items.Add(_expandCollapseMenuAction);

            #endregion

            #region 'Manage section' menu

            //Creates the 'Manage section' menu which holds the MenuAction items
            MenuGroup sectionFlyoutGroup =
                new MenuGroup("SectionGroup", "Manage section");
            sectionFlyoutGroup.HasDropDown = true;

            //Adds the MenuAction which moves the selected XPlorerSection up
            sectionFlyoutGroup.Items.Add(_moveUpMenuAction);
            _moveUpMenuAction.Execute += 
                new EventHandler<MenuActionEventArgs>(_moveUpMenuAction_Execute);

            //Adds the MenuAction which moves the selected XPlorerSection down
            sectionFlyoutGroup.Items.Add(_moveDownMenuAction);
            _moveDownMenuAction.Execute += 
                new EventHandler<MenuActionEventArgs>(_moveDownMenuAction_Execute);

            //Adds the MenuAction which sets the section as 'Primary'
            sectionFlyoutGroup.Items.Add(_IsPrimaryMenuAction);
            _IsPrimaryMenuAction.Execute += 
                new EventHandler<MenuActionEventArgs>(_IsPrimaryMenuAction_Execute);

            //Adds the menu to the ContextMenu provider
            this.Items.Add(sectionFlyoutGroup);

            #endregion

            #region 'Manage items' menu

            //Creates the 'Manage items' menu which holds the MenuAction items
            MenuGroup itemsFlyoutGroup =
                new MenuGroup("ItemsGroup", "Manage items");
            itemsFlyoutGroup.HasDropDown = true;

            //Adds the MenuAction which adds a new XPlorerItem to the XPlorerBar
            itemsFlyoutGroup.Items.Add(_addXPlorerItemMenuAction);
            _addXPlorerItemMenuAction.Execute += 
                new EventHandler<MenuActionEventArgs>(_addXPlorerItemMenuAction_Execute);

            //Adds the menu to the ContextMenu provider
            this.Items.Add(itemsFlyoutGroup);
            
            #endregion

            //Handles the event raised when the menu is about to be shown
            UpdateItemStatus += 
                new EventHandler<MenuActionEventArgs>(XPlorerSectionContextMenuProvider_UpdateItemStatus);
        }

        #endregion


        #region [       Updates the context menu       ]

        //===========================================================================
        /// <summary>
        /// Updates the context menu when it is about to be shown.
        /// </summary>
        /// <param name="sender">The object where the event handler is 
        /// attached.</param>
        /// <param name="e">The event data.</param>
        //===========================================================================
        private void XPlorerSectionContextMenuProvider_UpdateItemStatus(object sender, MenuActionEventArgs e)
        {
            //Gets a ModelItem which represents the selected control
            ModelItem selectedControl = e.Selection.PrimarySelection;

            #region 'Expand/Collapse' menu

            //Gets the value of the selected XPlorerSection 'IsExpanded' property
            ModelProperty isExpandedProperty =
                selectedControl.Properties[XPlorerSection.IsExpandedProperty];
            bool isExpanded = (bool)isExpandedProperty.ComputedValue;

            //Updates the menu item text according to the section status
            _expandCollapseMenuAction.DisplayName = (isExpanded ? "Collapse" : "Expand");

            #endregion

            #region 'Manage section' menu

            //Enables the 'Move up' item if the selected control is not the first section
            _moveUpMenuAction.Enabled =
                !ModelItemCollectionHelper.IsItFirstSection(selectedControl, parentChildrenRetrievalProperty);

            //Enables the 'Move down' item if the selected control is not the last section
            _moveDownMenuAction.Enabled =
                !ModelItemCollectionHelper.IsItLastSection(selectedControl, parentChildrenRetrievalProperty);

            //Enables and unchecks the 'IsPrimary' MenuAction item
            _IsPrimaryMenuAction.Enabled = true;
            _IsPrimaryMenuAction.Checkable = true;
            _IsPrimaryMenuAction.Checked = false;

            //Gets the value of the selected XPlorerSection 'IsPrimary' property
            ModelProperty isPrimaryProperty =
                selectedControl.Properties[XPlorerSection.IsPrimaryProperty];
            bool isPrimary = (bool)isPrimaryProperty.ComputedValue;

            //Updates the 'IsPrimary' MenuAction status
            _IsPrimaryMenuAction.Checked = isPrimary;

            #endregion
        }

        #endregion


        #region [       Expands or collapses the selected XPlorerSection       ]

        //===========================================================================
        /// <summary>
        /// Updates the 'IsExpanded' property of the selected XPlorerSection 
        /// according to the section status.
        /// </summary>
        /// <param name="sender">The object where the event handler is 
        /// attached.</param>
        /// <param name="e">The event data.</param>
        //===========================================================================
        private void _expandCollapseMenuAction_Execute(object sender, MenuActionEventArgs e)
        {
            //Gets a ModelItem which represents the selected control
            ModelItem selectedControl = e.Selection.PrimarySelection;

            //Gets the value of the selected XPlorerSection 'IsExpanded' property
            ModelProperty isExpandedProperty =
               selectedControl.Properties[XPlorerSection.IsExpandedProperty];
            bool isExpanded = (bool)isExpandedProperty.ComputedValue;

            //Updates the selected XPlorerSection 'IsExpanded' property
            isExpandedProperty.SetValue(!isExpanded);
        }

        #endregion


        #region [       Moves up and down the selected XPlorerSection       ]

        //===========================================================================
        /// <summary>
        /// Moves the selected XPlorerSection up in its parent container.
        /// </summary>
        /// <param name="sender">The object where the event handler is 
        /// attached.</param>
        /// <param name="e">The event data.</param>
        //===========================================================================
        private void _moveUpMenuAction_Execute(object sender, MenuActionEventArgs e)
        {
            //Gets a ModelItem which represents the selected control
            ModelItem selectedControl = e.Selection.PrimarySelection;

            //Moves the selected control up in its parent container
            ModelItemCollectionHelper.MoveItem(selectedControl, true, parentChildrenRetrievalProperty);
        }


        //===========================================================================
        /// <summary>
        /// Moves the selected XPlorerSection down in its parent container.
        /// </summary>
        /// <param name="sender">The object where the event handler is 
        /// attached.</param>
        /// <param name="e">The event data.</param>
        //===========================================================================
        private void _moveDownMenuAction_Execute(object sender, MenuActionEventArgs e)
        {
            //Gets a ModelItem which represents the selected control
            ModelItem selectedControl = e.Selection.PrimarySelection;

            //Moves the selected control down in its parent container
            ModelItemCollectionHelper.MoveItem(selectedControl, false, parentChildrenRetrievalProperty);
        }

        #endregion


        #region [       Adds a new XPlorerItem       ]

        //===========================================================================
        /// <summary>
        /// Adds a new XPlorerItem to the selected XPlorerSection.
        /// </summary>
        /// <param name="sender">The object where the event handler is 
        /// attached.</param>
        /// <param name="e">The event data.</param>
        //===========================================================================
        private void _addXPlorerItemMenuAction_Execute(object sender, MenuActionEventArgs e)
        {
            //Gets a ModelItem which represents the selected control
            ModelItem selectedControl = e.Selection.PrimarySelection;
            //and makes sure it is valid
            if (selectedControl == null)
                return;

            //Gets the selected XPlorerSection content
            ModelItem sectionContent = selectedControl.Properties["Content"].Value;

            //Makes sure the content of the selected XPlorerSection derived from Panel class
            if ((sectionContent == null) ||
                !sectionContent.ItemType.IsSubclassOf(typeof(Panel)))
            {
                MessageBox.Show("This operation requires a Panel element in XPlorerSection.Content",
                    "Warning message", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            //Opens edit mode
            using (ModelEditingScope batchedChange =
                selectedControl.BeginEdit("Adds a new XPlorerItem"))
            {
                //Creates a new XPlorerItem
                ModelItem newItem = ModelFactory.CreateItem(e.Context, typeof(XPlorerItem),
                    CreateOptions.InitializeDefaults, new Object[0]);
                //and adds it to the XPlorerSection.Content Panel children
                sectionContent.Properties["Children"].Collection.Add(newItem);

                //Commits all changes made in edit mode
                batchedChange.Complete();
            }
        }

        #endregion


        #region [       Sets the selected XPlorerSection 'IsPrimary' property       ]

        //===========================================================================
        /// <summary>
        /// Updates the 'IsPrimary' property of the selected XPlorerSection 
        /// according to the user choice.
        /// </summary>
        /// <param name="sender">The object where the event handler is 
        /// attached.</param>
        /// <param name="e">The event data.</param>
        //===========================================================================
        private void _IsPrimaryMenuAction_Execute(object sender, MenuActionEventArgs e)
        {
            //Gets a ModelItem which represents the selected control
            ModelItem selectedControl = e.Selection.PrimarySelection;

            //Gets the value of the selected XPlorerSection 'IsPrimary' property
            ModelProperty isPrimaryProperty =
                selectedControl.Properties[XPlorerSection.IsPrimaryProperty];

            //Gets the value of the item selected by the user
            bool selectedIsPrimary = ((MenuAction)sender).Checked;

            //Updates the selected XPlorerSection 'IsPrimary' property
            isPrimaryProperty.SetValue(selectedIsPrimary);
        }

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


Written By
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. [^]

Comments and Discussions