File: System\ComponentModel\Design\MenuCommand.cs
Web Access
Project: src\src\libraries\System.ComponentModel.TypeConverter\src\System.ComponentModel.TypeConverter.csproj (System.ComponentModel.TypeConverter)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Collections;
using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis;
 
namespace System.ComponentModel.Design
{
    /// <summary>
    /// Represents a Windows menu or toolbar item.
    /// </summary>
    public class MenuCommand
    {
        // Events that we suface or call on
        private readonly EventHandler? _execHandler;
 
        private int _status;
        private IDictionary? _properties;
 
        /// <summary>
        /// Indicates that the given command is enabled. An enabled command may
        /// be selected by the user (it's not greyed out).
        /// </summary>
        private const int ENABLED = 0x02;  //tagOLECMDF.OLECMDF_ENABLED;
 
        /// <summary>
        /// Indicates that the given command is not visible on the command bar.
        /// </summary>
        private const int INVISIBLE = 0x10;
 
        /// <summary>
        /// Indicates that the given command is checked in the "on" state.
        /// </summary>
        private const int CHECKED = 0x04; // tagOLECMDF.OLECMDF_LATCHED;
 
        /// <summary>
        /// Indicates that the given command is supported. Marking a command
        /// as supported indicates that the shell will not look any further up
        /// the command target chain.
        /// </summary>
        private const int SUPPORTED = 0x01; // tagOLECMDF.OLECMDF_SUPPORTED
 
        /// <summary>
        /// Initializes a new instance of <see cref='System.ComponentModel.Design.MenuCommand'/>.
        /// </summary>
        public MenuCommand(EventHandler? handler, CommandID? command)
        {
            _execHandler = handler;
            CommandID = command;
            _status = SUPPORTED | ENABLED;
        }
 
        /// <summary>
        /// Gets or sets a value indicating whether this menu item is checked.
        /// </summary>
        public virtual bool Checked
        {
            get => (_status & CHECKED) != 0;
            set => SetStatus(CHECKED, value);
        }
 
        /// <summary>
        /// Gets or sets a value indicating whether this menu item is available.
        /// </summary>
        public virtual bool Enabled
        {
            get => (_status & ENABLED) != 0;
            set => SetStatus(ENABLED, value);
        }
 
        private void SetStatus(int mask, bool value)
        {
            int newStatus = _status;
 
            if (value)
            {
                newStatus |= mask;
            }
            else
            {
                newStatus &= ~mask;
            }
 
            if (newStatus != _status)
            {
                _status = newStatus;
                OnCommandChanged(EventArgs.Empty);
            }
        }
 
        public virtual IDictionary Properties => _properties ??= new HybridDictionary();
 
        /// <summary>
        /// Gets or sets a value indicating whether this menu item is supported.
        /// </summary>
        public virtual bool Supported
        {
            get => (_status & SUPPORTED) != 0;
            set => SetStatus(SUPPORTED, value);
        }
 
        /// <summary>
        /// Gets or sets a value indicating if this menu item is visible.
        /// </summary>
        public virtual bool Visible
        {
            get => (_status & INVISIBLE) == 0;
            set => SetStatus(INVISIBLE, !value);
        }
 
        /// <summary>
        /// Occurs when the menu command changes.
        /// </summary>
        public event EventHandler? CommandChanged;
 
 
        /// <summary>
        /// Gets the <see cref='System.ComponentModel.Design.CommandID'/> associated with this menu command.
        /// </summary>
        public virtual CommandID? CommandID { get; }
 
        /// <summary>
        /// Invokes a menu item.
        /// </summary>
        public virtual void Invoke()
        {
            if (_execHandler != null)
            {
                try
                {
                    _execHandler(this, EventArgs.Empty);
                }
                catch (CheckoutException cxe)
                {
                    if (cxe == CheckoutException.Canceled)
                        return;
 
                    throw;
                }
            }
        }
 
        /// <summary>
        /// Invokes a menu item. The default implementation of this method ignores
        /// the argument, but deriving classes may override this method.
        /// </summary>
        public virtual void Invoke(object arg) => Invoke();
 
        /// <summary>
        /// Gets the OLE command status code for this menu item.
        /// </summary>
        public virtual int OleStatus => _status;
 
        /// <summary>
        /// Provides notification and is called in response to
        /// a <see cref='System.ComponentModel.Design.MenuCommand.CommandChanged'/> event.
        /// </summary>
        protected virtual void OnCommandChanged(EventArgs e) => CommandChanged?.Invoke(this, e);
 
        /// <summary>
        /// Overrides object's ToString().
        /// </summary>
        public override string ToString()
        {
            string str = (CommandID?.ToString() ?? "") + " : ";
            if ((_status & SUPPORTED) != 0)
            {
                str += "Supported";
            }
            if ((_status & ENABLED) != 0)
            {
                str += "|Enabled";
            }
            if ((_status & INVISIBLE) == 0)
            {
                str += "|Visible";
            }
            if ((_status & CHECKED) != 0)
            {
                str += "|Checked";
            }
            return str;
        }
    }
}