7

C# (VSTO)を使用して (セル、範囲)コンテキスト メニューを無効化または構成することは可能ですか。はいの場合、どのように実装できますか (ドキュメント レベルの VSTO Excel アプリケーションで)

たとえば、コンテキスト メニューの一部の項目 (コピー/貼り付けなど) を無効にして、新しい項目を追加したり、標準のコンテキスト メニューを完全な独自のメニューに置き換えたりしたいと考えています。

スマートタグは、Excel のコンテキスト メニューに代わる優れた方法ですか?

4

1 に答える 1

17
  • コメント付きの大まかなサンプルコードを次に示します
  • これはVS2010で作成され、 Excel 2010に対してテストされています
  • 最初のステップは、新しいExcel 2010 アドインプロジェクトを作成することでした
  • 次に、 ThisAddin.cs内で生成された既定のコードに、以下のサンプル コードを追加しました。
  • このコードは、「abc」を含む単一のセルを右クリックすると、新しいメニュー項目を追加し、カット/コピー/ペースト メニュー項目を削除します。これは、セルの内容に基づいてコンテキスト メニューを変更することをシミュレートするためです。


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;
    using Excel = Microsoft.Office.Interop.Excel;
    using Office = Microsoft.Office.Core;
    using Microsoft.Office.Tools.Excel;
    using System.Diagnostics;
    using Microsoft.Office.Interop.Excel;

    namespace Excel_Menu
    {
        public partial class ThisAddIn
        {
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                ResetCellMenu();  // reset the cell context menu back to the default

                // Call this function is the user right clicks on a cell
                this.Application.SheetBeforeRightClick+=new Excel.AppEvents_SheetBeforeRightClickEventHandler(Application_SheetBeforeRightClick);
            }

            private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
            {
            }

            private Office.CommandBar GetCellContextMenu()
            {
                return this.Application.CommandBars["Cell"];
            }

            private void ResetCellMenu()
            {
                GetCellContextMenu().Reset(); // reset the cell context menu back to the default
            }

            private void Application_SheetBeforeRightClick(object Sh, Range Target, ref bool Cancel)
            {
                ResetCellMenu();  // reset the cell context menu back to the default

                if (Target.Cells.Count == 1)   // sample code: if only a single cell is selected
                {
                    if (Target.Cells[1, 1].Value == "abc") // sample code: if the signle cell contains 'abc'
                    {
                        AddExampleMenuItem();
                        RemoveCutCopyPasteMenuItems();
                    }
                }
            }

            private void AddExampleMenuItem()
            {
                Office.MsoControlType menuItem = Office.MsoControlType.msoControlButton;
                Office.CommandBarButton exampleMenuItem = (Office.CommandBarButton)GetCellContextMenu().Controls.Add(menuItem, missing, missing, 1, true);

                exampleMenuItem.Style = Office.MsoButtonStyle.msoButtonCaption;
                exampleMenuItem.Caption = "Example Menu Item";
                exampleMenuItem.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(exampleMenuItemClick);
            }

            private void RemoveCutCopyPasteMenuItems()
            {
                Office.CommandBar contextMenu = GetCellContextMenu();

                for (int i = contextMenu.Controls.Count; i > 0; i--)
                {
                    Office.CommandBarControl control = contextMenu.Controls[i];

                    if (control.Caption == "Cu&t") control.Delete();  // Sample code: remove cut menu item
                    else if (control.Caption == "&Copy") control.Delete();  // Sample code: remove copy menu item
                    else if (control.accDescription.Contains("Paste")) control.Delete(); // Sample code: remove any paste menu items
                }
            }

            void exampleMenuItemClick(Microsoft.Office.Core.CommandBarButton Ctrl, ref bool CancelDefault)
            {
                System.Windows.Forms.MessageBox.Show("Example Menu Item clicked");
            }

            #region VSTO generated code

            /// 
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// 
            private void InternalStartup()
            {
                this.Startup += new System.EventHandler(ThisAddIn_Startup);
                this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
            }

            #endregion
        }
    }


于 2013-08-19T19:36:13.597 に答える