Menu.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / System / Windows / Controls / Menu.cs / 1 / Menu.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
//
// File: Menu.cs 
//
//--------------------------------------------------------------------------- 
using MS.Internal; 
using MS.Internal.KnownBoxes;
using MS.Utility; 
using System.ComponentModel;

using System.Diagnostics;
using System.Windows.Threading; 

#if OLD_AUTOMATION 
using System.Windows.Automation.Provider; 
#endif
using System.Windows.Media; 
using System.Windows.Input;
using System.Windows.Controls.Primitives;

using System; 
using System.Security;
using System.Security.Permissions; 
 
namespace System.Windows.Controls
{ 
    /// 
    ///     Control that defines a menu of choices for users to invoke.
    /// 
#if OLD_AUTOMATION 
    [Automation(AccessibilityControlType = "Menu")]
#endif 
    public class Menu : MenuBase 
    {
        //------------------------------------------------------------------- 
        //
        //  Constructors
        //
        //------------------------------------------------------------------- 

        #region Constructors 
 
        /// 
        ///     Default DependencyObject constructor 
        /// 
        /// 
        ///     Automatic determination of current Dispatcher. Use alternative constructor
        ///     that accepts a Dispatcher for best performance. 
        /// 
        public Menu() : base() 
        { 
        }
 
        static Menu()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Menu), new FrameworkPropertyMetadata(typeof(Menu)));
            _dType = DependencyObjectType.FromSystemTypeInternal(typeof(Menu)); 

            ItemsPanelProperty.OverrideMetadata(typeof(Menu), new FrameworkPropertyMetadata(GetDefaultPanel())); 
            IsTabStopProperty.OverrideMetadata(typeof(Menu), new FrameworkPropertyMetadata(false)); 

            KeyboardNavigation.ControlTabNavigationProperty.OverrideMetadata(typeof(Menu), new FrameworkPropertyMetadata(KeyboardNavigationMode.Once)); 
            KeyboardNavigation.DirectionalNavigationProperty.OverrideMetadata(typeof(Menu), new FrameworkPropertyMetadata(KeyboardNavigationMode.Cycle));

            EventManager.RegisterClassHandler(typeof(Menu), AccessKeyManager.AccessKeyPressedEvent, new AccessKeyPressedEventHandler(OnAccessKeyPressed));
        } 

        private static ItemsPanelTemplate GetDefaultPanel() 
        { 
            FrameworkElementFactory panel = new FrameworkElementFactory(typeof(WrapPanel));
            ItemsPanelTemplate template = new ItemsPanelTemplate(panel); 
            template.Seal();
            return template;
        }
 
        #endregion
 
 
        //--------------------------------------------------------------------
        // 
        //  Public Methods
        //
        //-------------------------------------------------------------------
 
        /// 
        ///     DependencyProperty for the IsMainMenuProperty 
        ///  
        public static readonly DependencyProperty IsMainMenuProperty =
                DependencyProperty.Register( 
                        "IsMainMenu",
                        typeof(bool),
                        typeof(Menu),
                        new FrameworkPropertyMetadata( 
                                BooleanBoxes.TrueBox,
                                new PropertyChangedCallback(OnIsMainMenuChanged))); 
 
        /// 
        ///     True if this menu will participate in main menu activation notification. 
        ///     If there are multiple menus on a page, menus that do not wish to receive ALT or F10
        ///     key notification should set this property to false.
        /// 
        ///  
        public bool IsMainMenu
        { 
            get { return (bool) GetValue(IsMainMenuProperty); } 
            set { SetValue(IsMainMenuProperty, BooleanBoxes.Box(value)); }
        } 

        private static void OnIsMainMenuChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Menu menu = d as Menu; 
            if ((bool) e.NewValue)
            { 
                menu.SetupMainMenu(); 
            }
            else 
            {
                menu.CleanupMainMenu();
            }
        } 

        ///  
        /// Creates AutomationPeer () 
        /// 
        protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer() 
        {
            return new System.Windows.Automation.Peers.MenuAutomationPeer(this);
        }
 
        /// 
        ///     This virtual method in called when IsInitialized is set to true and it raises an Initialized event 
        ///  
        protected override void OnInitialized(EventArgs e)
        { 
            base.OnInitialized(e);
            if (IsMainMenu)
            {
                SetupMainMenu(); 
            }
        } 
 
        /// 
        ///    Critical: This sets up a handler for entering menu mode which will recieve a presentationsource 
        ///    TreatAsSafe: The function that it hooks is safe to expose since it does not expose the source
        /// 
        [SecurityCritical,SecurityTreatAsSafe]
        private void SetupMainMenu() 
        {
            if (_enterMenuModeHandler == null) 
            { 
                _enterMenuModeHandler = new KeyboardNavigation.EnterMenuModeEventHandler(OnEnterMenuMode);
                (new UIPermission(UIPermissionWindow.AllWindows)).Assert(); //Blessed Assert 
                try
                {
                   KeyboardNavigation.Current.EnterMenuMode += _enterMenuModeHandler;
                } 
                finally
                { 
                    UIPermission.RevertAssert(); 
                }
           } 
       }

        private void CleanupMainMenu()
        { 
            if (_enterMenuModeHandler != null)
            { 
                KeyboardNavigation.Current.EnterMenuMode -= _enterMenuModeHandler; 
            }
        } 

        private static object OnGetIsMainMenu(DependencyObject d)
        {
            return BooleanBoxes.Box(((Menu)d).IsMainMenu); 
        }
 
        //-------------------------------------------------------------------- 
        //
        //  Protected Methods 
        //
        //--------------------------------------------------------------------

        #region Protected Methods 

        ///  
        /// Prepare the element to display the item.  This may involve 
        /// applying styles, setting bindings, etc.
        ///  
        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            base.PrepareContainerForItemOverride(element, item);
 
            MenuItem.PrepareMenuItem(element, item);
        } 
 
        /// 
        ///     This is the method that responds to the KeyDown event. 
        /// 
        /// Event arguments
        protected override void OnKeyDown(KeyEventArgs e)
        { 
            base.OnKeyDown(e);
            if (e.Handled) return; 
 
            Key key = e.Key;
            switch (key) 
            {
                case Key.Down:
                case Key.Up:
                    if (CurrentSelection != null) 
                    {
                        // Only for non vertical layout Up/Down open the submenu 
                        Panel itemsHost = ItemsHost; 
                        bool isVertical = itemsHost != null && itemsHost.HasLogicalOrientation && itemsHost.LogicalOrientation == Orientation.Vertical;
                        if (!isVertical) 
                        {
                            CurrentSelection.OpenSubmenuWithKeyboard();
                            e.Handled = true;
                        } 
                    }
                    break; 
                case Key.Left: 
                case Key.Right:
                    if (CurrentSelection != null) 
                    {
                        // Only for vertical layout Left/Right open the submenu
                        Panel itemsHost = ItemsHost;
                        bool isVertical = itemsHost != null && itemsHost.HasLogicalOrientation && itemsHost.LogicalOrientation == Orientation.Vertical; 
                        if (isVertical)
                        { 
                            CurrentSelection.OpenSubmenuWithKeyboard(); 
                            e.Handled = true;
                        } 
                    }
                    break;
            }
        } 

        ///  
        ///     Called when any mouse button is pressed or released on this subtree 
        /// 
        /// Event arguments. 
        protected override void HandleMouseButton(MouseButtonEventArgs e)
        {
            base.HandleMouseButton(e);
 
            if (e.Handled)
            { 
                return; 
            }
 
            if (e.ChangedButton != MouseButton.Left && e.ChangedButton != MouseButton.Right)
            {
                return;
            } 

            // We want to dismiss when someone clicks on the menu bar, so 
            // really we're interested in clicks that bubble up from an 
            // element whose TemplatedParent is the Menu.
            if (IsMenuMode) 
            {
                FrameworkElement element = e.OriginalSource as FrameworkElement;

                if ((element != null && (element == this || element.TemplatedParent == this))) 
                {
                    IsMenuMode = false; 
                    e.Handled = true; 
                }
            } 
        }

        internal override void FocusItem(object item, ItemNavigateArgs itemNavigateArgs)
        { 
            base.FocusItem(item, itemNavigateArgs);
            // Trying to navigate from the current menuitem (this) to an adjacent menuitem. 
 
            if (itemNavigateArgs.DeviceUsed is KeyboardDevice)
            { 
                // If the item is a TopLevelHeader then when you navigate onto it, the submenu will open
                // and we should select the first item in the submenu.  The parent MenuItem will take care
                // of opening the submenu but doesn't know whether focus changed because of a mouse action
                // or a keyboard action.  Help out by focusing the first thing in the new submenu. 

                // Assume that KeyboardNavigation.Current.Navigate moved focus onto the element onto which 
                // it navigated. 
                MenuItem newSelection = ItemContainerGenerator.ContainerFromItem(item) as MenuItem;
                if (newSelection != null 
                    && newSelection.Role == MenuItemRole.TopLevelHeader
                    && newSelection.IsSubmenuOpen)
                {
                    newSelection.NavigateToStart(itemNavigateArgs); 
                }
            } 
        } 

        #endregion 

        //-------------------------------------------------------------------
        //
        //  Private Methods 
        //
        //-------------------------------------------------------------------- 
 
        #region Private Methods
 
        private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
        {
            // If ALT is down, then blend our scope into the one above. Maybe bad, but only if Menu is not top-level.
            if (!(Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))) 
            {
                e.Scope = sender; 
                e.Handled = true; 
            }
        } 

        /// 
        /// Critical - as this calls PresentationSource.CriticalFromVisual() .
        /// Safe - as this doesn't return PresentationSource thus obtained. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private bool OnEnterMenuMode(object sender, EventArgs e) 
        {
            // Don't enter menu mode if someone has capture 
            if (Mouse.Captured != null)
                return false;

            // Need to check that ALT/F10 happened in our source. 
            PresentationSource source = sender as PresentationSource;
            PresentationSource mySource = null; 
 
            mySource = PresentationSource.CriticalFromVisual(this);
            if (source == mySource) 
            {
                // Give focus to the first possible element in the ItemsControl
                for (int i = 0; i < Items.Count; i++)
                { 
                    MenuItem menuItem = ItemContainerGenerator.ContainerFromIndex(i) as MenuItem;
 
                    if (menuItem != null && !(Items[i] is Separator)) 
                    {
                        if (menuItem.Focus()) 
                        {
                            return true;
                        }
                    } 
                }
            } 
 
            return false;
        } 

        //
        //  This property
        //  1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject 
        //  2. This is a performance optimization
        // 
        internal override int EffectiveValuesInitialSize 
        {
            get { return 28; } 
        }

        #endregion
 
        //-------------------------------------------------------------------
        // 
        //  Private Fields 
        //
        //------------------------------------------------------------------- 

        #region Private Fields

        private KeyboardNavigation.EnterMenuModeEventHandler _enterMenuModeHandler; 

        #endregion 
 
        #region DTypeThemeStyleKey
 
        // Returns the DependencyObjectType for the registered ThemeStyleKey's default
        // value. Controls will override this method to return approriate types.
        internal override DependencyObjectType DTypeThemeStyleKey
        { 
            get { return _dType; }
        } 
 
        private static DependencyObjectType _dType;
 
        #endregion DTypeThemeStyleKey
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK