Menu.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / Menu.cs / 1458001 / 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;
            }
        } 

        ///  
        ///     This is the method that responds to the TextInput event. 
        /// 
        /// Event arguments 
        /// 
        ///     Critical: accesses ShowSystemMenu & CriticalFromVisual
        ///     TreatAsSafe: limited to only UserInitiated input.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        protected override void OnTextInput(TextCompositionEventArgs e) 
        { 
            base.OnTextInput(e);
            if (e.Handled) return; 

            // We don't use win32 menu's, so we need to emulate the win32
            // behavior for hitting Space while in menu mode.  Alt+Space
            // will be handled as a SysKey by the DefaultWindowProc, but 
            // Alt, then Space needs to be special cased here because we prevent win32.
            // from entering menu mode.  In WPF the equiv. of win32 menu mode is having 
            // a main menu with focus and no menu items opened. 
            if (e.UserInitiated &&
                e.Text == " " && 
                IsMainMenu &&
                (CurrentSelection == null || !CurrentSelection.IsSubmenuOpen))
            {
                // We need to exit menu mode because it holds capture and prevents 
                // the system menu from showing.
                IsMenuMode = false; 
                System.Windows.Interop.HwndSource source = PresentationSource.CriticalFromVisual(this) as System.Windows.Interop.HwndSource; 
                if (source != null)
                { 
                    source.ShowSystemMenu();
                    e.Handled = true;
                }
            } 
        }
 
        ///  
        ///     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