Top / .NET備忘録 / 07.Form / 06.PopupMenu

PopupMenu メソッドを実装します。

VB6.0 の PopupMenu メソッドは、メニューからコンテキストメニューを作成しているので、それに倣い、ToolStripMenuItem から ContextMenuStrip を作成して表示します。

引数はいろいろありますが、ほとんど使ってないので、ひとつだけ。(^_^;)

 public void PopupMenu(ToolStripMenuItem menu)
 {
     ContextMenuStrip popup = new VBPopupMenu(menu);
     Point mouseClientPosition = this.PointToClient(Control.MousePosition);
     popup.Show(this, mouseClientPosition);
 }

ContextMenuStrip を継承して、VBPopupMenu クラスを作成します。

詳細は端折っちゃいますが、ひとつだけ注意。

Click イベントの呼び出しです。

ToolStripItem.PerformClick では、Enabled かつ Available でなければ、OnClick メソッドが呼び出されず、イベントが発生しません。

リフレクションを使って、OnClick メソッドを呼び出す必要があります。

 using System;
 using System.Collections.Generic;
 using System.Windows.Forms;
 using System.Reflection;
 
 namespace VB6Control
 {
     public class VBPopupMenu : ContextMenuStrip
     {
 
         ToolStripMenuItem m_Menu;
 
         // PerformClick は Enabled && Available でなければイベントを起動しない
         // Reflection で OnClick を呼び出す
         private static void InvokeOnClick(object target)
         {
             Type typ = target.GetType();
             MethodInfo mi = typ.GetMethod("OnClick", BindingFlags.NonPublic | BindingFlags.Instance);
             mi.Invoke(target, new object[] { EventArgs.Empty });
         }
 
         public VBPopupMenu(ToolStripMenuItem menu)
         {
             m_Menu = menu;
 
             base.Items.Clear();
             foreach (ToolStripItem item in menu.DropDownItems)
             {
                 AddMenu(null, item);
             }
         }
 
         private void AddMenu(ToolStripMenuItem parent, ToolStripItem current)
         {
             ToolStripSeparator separator = current as ToolStripSeparator;
             if (separator != null)
             {
                 if (parent == null)
                     base.Items.Add(new ToolStripSeparator());
                 else
                     parent.DropDownItems.Add(new ToolStripSeparator());
             }
             else
             {
                 ToolStripMenuItem menuItem = current as ToolStripMenuItem;
                 if (menuItem != null)
                 {
                     ToolStripMenuItem currentMenuItem = new VBPopupMenuItem(menuItem);
                     if (parent == null)
                         base.Items.Add(currentMenuItem);
                     else
                         parent.DropDownItems.Add(currentMenuItem);
 
                     if (menuItem.HasDropDownItems)
                         foreach (ToolStripItem item in menuItem.DropDownItems)
                         {
                             AddMenu(currentMenuItem, item);
                         }
                 }
             }
         }
 
         protected override void OnOpening(System.ComponentModel.CancelEventArgs e)
         {
             InvokeOnClick(m_Menu);
             base.OnOpening(e);
         }
 
         internal class VBPopupMenuItem : ToolStripMenuItem
         {
             ToolStripMenuItem m_MenuItem;
 
             public VBPopupMenuItem(ToolStripMenuItem menuItem)
                 : base(menuItem.Text, menuItem.Image)
             {
                 m_MenuItem = menuItem;
 
                 // プロパティをコピー
 
                 base.Checked = menuItem.Checked;
                 base.CheckState = menuItem.CheckState;
                 base.Enabled = menuItem.Enabled;
                 base.ForeColor = menuItem.ForeColor;
                 base.Font = menuItem.Font;
                 base.Available = menuItem.Available;    // Available ≒ Visible
                 base.ShortcutKeys = menuItem.ShortcutKeys;
                 base.ShowShortcutKeys = menuItem.ShowShortcutKeys;
 
                 // プロパティの変更をキャッチ
                 menuItem.CheckedChanged += menuItem_CheckedChanged;
                 menuItem.CheckStateChanged += menuItem_CheckStateChanged;
                 menuItem.EnabledChanged += menuItem_EnabledChanged;
                 menuItem.ForeColorChanged += menuItem_ForeColorChanged;
                 menuItem.TextChanged += menuItem_TextChanged;
                 menuItem.VisibleChanged += menuItem_VisibleChanged;
             }
 
             // メニューが操作されたときのイベント取得
 
             void menuItem_VisibleChanged(object sender, EventArgs e)
             {
                 base.Visible = m_MenuItem.Visible;
             }
 
             void menuItem_TextChanged(object sender, EventArgs e)
             {
                 base.Text = m_MenuItem.Text;
             }
 
             void menuItem_ForeColorChanged(object sender, EventArgs e)
             {
                 base.ForeColor = m_MenuItem.ForeColor;
             }
 
             void menuItem_EnabledChanged(object sender, EventArgs e)
             {
                 base.Enabled = m_MenuItem.Enabled;
             }
 
             void menuItem_CheckStateChanged(object sender, EventArgs e)
             {
                 base.CheckState = m_MenuItem.CheckState;
             }
 
             void menuItem_CheckedChanged(object sender, EventArgs e)
             {
                 base.Checked = m_MenuItem.Checked;
             }
 
             // クリックされたとき、元メニューのクリックイベントを起こす
 
             protected override void OnClick(EventArgs e)
             {
                 InvokeOnClick(m_MenuItem);
                 base.OnClick(e);
             }
         }
     }
 }



トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   最終更新のRSS
Last-modified: 2013-12-29 (日) 03:44:01 (1447d)