簡體   English   中英

如何將控件作為工具欄添加到 ContextMenuStrip?

[英]How to add Controls, as a toolbar, to a ContextMenuStrip?

我正在制作 Web 瀏覽器,但我不知道如何在其 ContextMenuStrip 頂部添加這些按鈕:

在此處輸入圖像描述

分隔符為所有項目創建列,但只為一行創建列。
你知道怎么做嗎?

這是一個自定義組件,繼承了承載 UserControl 而不是標准控件的ToolStripControlHost (如 .Net 的ToolStripTextBoxToolStripComboBox等)。

▶ 構建一個 UserControl,您可以將任何其他控件添加到其表面並照常管理它們的操作,除了 UserControl 的事件通過ToolStripControlHost派生的 object 公開,因此實施者不需要了解有關底層托管控件的任何信息。

您要公開的托管控件的事件訂閱覆蓋OnSubscribeControlEvents() (當然取消訂閱覆蓋OnUnsubscribeControlEvents ),然后引發相關或組合事件,根據需要返回值。

▶ 這顯示在ToolStripControlHost class 中,請參閱public event EventHandler<UserActionArgs> ButtonAction事件,該事件返回自定義EventArgs參數,其中包括確定單擊按鈕執行的操作所需的元素。

需要時,托管控件通過ToolStripControlHost.Control屬性公開。


您可以在使用它的 Form 的構造函數中初始化現有的 ContextMenuStrip ( contextMenuStrip1 ):

public partial class Form1 : Form
{
    private ToolStripUserControl toolStripUC = new ToolStripUserControl();

    public Form1()
    {
        InitializeComponent();

        // Assigns an existing ContextMenuStrip, to the Form or any other Control
        this.ContextMenuStrip = contextMenuStrip1;

        // Inserts the ToolStripUserControl and a Separator
        contextMenuStrip1.Items.Insert(0, new ToolStripSeparator());
        contextMenuStrip1.Items.Insert(0, toolStripUC);

        // Subscribes to the ButtonAction event
        toolStripUC.ButtonAction += (s, e) 
            => { this.Text = $"Your Action is {e.UserAction}, triggered by {e.TriggerControl.Name}"; };
        contextMenuStrip1.Closed += (s, e) => this.Text = "Right-Click on me";
    }
}

ToolStripControlHost派生的 class:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

[ToolboxItem(false)]
public class ToolStripUserControl : ToolStripControlHost
{
    // Pass the UserControl, MenuStripNavigationBar, to the base class.
    public ToolStripUserControl() : base(new MenuStripNavigationBar()) { }

    public MenuStripNavigationBar NavigatorBar => Control as MenuStripNavigationBar;

    // Exposes the ButtonActions Dictionary, to redefine the Buttons' actions
    public Dictionary<Control, ButtonAction> ButtonActions {
        get => NavigatorBar.ButtonActions;
        set => NavigatorBar.ButtonActions = value;
    }

    // Subscribe to the events you want to expose...
    protected override void OnSubscribeControlEvents(Control ctl)
    {
        base.OnSubscribeControlEvents(ctl);
        var navigatorBar = (MenuStripNavigationBar)ctl;
        navigatorBar.UserAction += OnButtonAction;
    }

    // ...and then unsubscribe. This is called when the Form is destroyed
    protected override void OnUnsubscribeControlEvents(Control ctl)
    {
        base.OnUnsubscribeControlEvents(ctl);
        var navigatorBar = (MenuStripNavigationBar)ctl;
        navigatorBar.UserAction -= OnButtonAction;
    }

    // Exposes a public custom event
    public event EventHandler<UserActionArgs> ButtonAction;

    // Raises the event when an UserAction is triggered
    private void OnButtonAction(object sender, EventArgs e)
    {
        var ctl = sender as Control;
        var userAction = new UserActionArgs(ButtonActions[ctl], ctl);
        ButtonAction?.Invoke(this, userAction);
    }
}

自定義 EventArgs object

public class UserActionArgs : EventArgs
{
    public UserActionArgs(ButtonAction action, Control control)
    {
        this.UserAction = action;
        this.TriggerControl = control;
    }
    public ButtonAction UserAction { get; }
    public Control TriggerControl { get; }
}

動作枚舉器

public enum ButtonAction
{
    MoveBack,
    MoveForward,
    PlayMusic,
    PlayAnimation
}

這是它的工作原理:

ToolStripControlHost 用戶控件

這是完整的 UserControl,以簡化測試:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

public partial class MenuStripNavigationBar : UserControl
{
    public event EventHandler UserAction;

    public MenuStripNavigationBar()
    {
        InitializeComponent();
        this.ButtonActions = new Dictionary<Control, ButtonAction>();

        this.buttonArrowLeft.Text = "⏪";
        ButtonActions.Add(this.buttonArrowLeft, ButtonAction.MoveBack);
        this.buttonArrowLeft.Click += ButtonsActionEvent;

        this.buttonArrowRight.Text = "⏩";
        ButtonActions.Add(this.buttonArrowRight, ButtonAction.MoveBack);
        this.buttonArrowRight.Click += ButtonsActionEvent;

        this.buttonMusicKey.Text = "♬";
        ButtonActions.Add(this.buttonMusicKey, ButtonAction.PlayMusic);
        this.buttonMusicKey.Click += ButtonsActionEvent;

        this.buttonAction.Text = "⛄";
        ButtonActions.Add(this.buttonAction, ButtonAction.PlayAnimation);
        this.buttonAction.Click += ButtonsActionEvent;
    }

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public Dictionary<Control, ButtonAction> ButtonActions { get; set; }

    private void ButtonsActionEvent(object sender, EventArgs e) 
        => UserAction?.Invoke(sender, e);


    [ToolboxItem(false)]
    internal class ButtonPanel : Panel
    {
        private Color borderActiveColor = Color.LightSteelBlue;
        private Color borderInactiveColor = Color.Gray;
        private Color borderColor = Color.Transparent;

        public ButtonPanel()
        {
            this.SetStyle(ControlStyles.Selectable | ControlStyles.SupportsTransparentBackColor | 
                          ControlStyles.UserMouse | ControlStyles.StandardClick, true);
            this.UpdateStyles();
            this.BackColor = Color.Transparent;
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            this.OnEnter(e);
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            this.OnLeave(e);
        }

        protected override void OnEnter(EventArgs e)
        {
            base.OnEnter(e);
            bool hovered = this.ClientRectangle.Contains(this.PointToClient(MousePosition));
            borderColor = hovered ? Enabled ? borderActiveColor : borderInactiveColor : Color.Transparent;
            this.Invalidate();
        }

        protected override void OnLeave(EventArgs e)
        {
            if (this.ClientRectangle.Contains(this.PointToClient(MousePosition))) return;
            borderColor = Color.Transparent;
            base.OnLeave(e);
            this.Invalidate();
        }

        TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | 
            TextFormatFlags.NoPadding | TextFormatFlags.PreserveGraphicsClipping | TextFormatFlags.SingleLine;

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            var textRect = Rectangle.Inflate(ClientRectangle, 0, -1);
            TextRenderer.DrawText(e.Graphics, Text, Font, textRect, ForeColor, Color.Empty, flags);
            ControlPaint.DrawBorder(e.Graphics, ClientRectangle, borderColor, ButtonBorderStyle.Solid);
        }
    }
}

設計師文件:

partial class MenuStripNavigationBar
{
    private System.ComponentModel.IContainer components = null;

    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null)) {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    private void InitializeComponent()
    {
        this.buttonAction = new MenuStripNavigationBar.ButtonPanel();
        this.buttonArrowLeft = new MenuStripNavigationBar.ButtonPanel();
        this.buttonArrowRight = new MenuStripNavigationBar.ButtonPanel();
        this.buttonMusicKey = new MenuStripNavigationBar.ButtonPanel();
        this.SuspendLayout();
        // 
        // buttonAction
        // 
        this.buttonAction.BackColor = System.Drawing.Color.Transparent;
        this.buttonAction.Font = new System.Drawing.Font("Segoe UI Symbol", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        this.buttonAction.Location = new System.Drawing.Point(166, 2);
        this.buttonAction.Name = "buttonAction";
        this.buttonAction.Size = new System.Drawing.Size(42, 26);
        this.buttonAction.TabIndex = 0;
        // 
        // buttonArrowLeft
        // 
        this.buttonArrowLeft.BackColor = System.Drawing.Color.Transparent;
        this.buttonArrowLeft.Font = new System.Drawing.Font("Segoe UI Symbol", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        this.buttonArrowLeft.Location = new System.Drawing.Point(3, 2);
        this.buttonArrowLeft.Name = "buttonArrowLeft";
        this.buttonArrowLeft.Size = new System.Drawing.Size(42, 26);
        this.buttonArrowLeft.TabIndex = 0;
        // 
        // buttonArrowRight
        // 
        this.buttonArrowRight.BackColor = System.Drawing.Color.Transparent;
        this.buttonArrowRight.Font = new System.Drawing.Font("Segoe UI Symbol", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        this.buttonArrowRight.Location = new System.Drawing.Point(58, 2);
        this.buttonArrowRight.Name = "buttonArrowRight";
        this.buttonArrowRight.Size = new System.Drawing.Size(42, 26);
        this.buttonArrowRight.TabIndex = 0;
        // 
        // buttonMusicKey
        // 
        this.buttonMusicKey.BackColor = System.Drawing.Color.Transparent;
        this.buttonMusicKey.Font = new System.Drawing.Font("Segoe UI Symbol", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        this.buttonMusicKey.Location = new System.Drawing.Point(112, 2);
        this.buttonMusicKey.Name = "buttonMusicKey";
        this.buttonMusicKey.Size = new System.Drawing.Size(42, 26);
        this.buttonMusicKey.TabIndex = 0;
        // 
        // MenuStripNavigationBar
        // 
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
        this.BackColor = System.Drawing.Color.Transparent;
        this.Controls.Add(this.buttonMusicKey);
        this.Controls.Add(this.buttonArrowRight);
        this.Controls.Add(this.buttonArrowLeft);
        this.Controls.Add(this.buttonAction);
        this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        this.MaximumSize = new System.Drawing.Size(212, 30);
        this.MinimumSize = new System.Drawing.Size(212, 30);
        this.Name = "MenuStripNavigationBar";
        this.Size = new System.Drawing.Size(212, 30);
        this.ResumeLayout(false);
    }

    private ButtonPanel buttonAction;
    private ButtonPanel buttonArrowLeft;
    private ButtonPanel buttonArrowRight;
    private ButtonPanel buttonMusicKey;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM