2013-11-15 89 views
1

我想,當我點擊菜單項上,展示的物品,諸如「刪除」,「重命名」等如何的ContextMenuStrip添加到ToolStripMenuItem

如何把自己綁定一個上下文菜單時上下文菜單你右鍵單擊菜單項?

+2

WPF or Winforms? –

+0

您可以提供一個特殊的'ToolStripMenuItem' *編輯菜單*項目,打開對話框來編輯菜單的某個部分。 – Sinatr

回答

1

第一個跳躍在我腦海的想法是在ToolStripMenuItem上掛上一些MouseDown事件,並在屏幕座標中的鼠標位置顯示第二個ContextMenuStrip。但並非如此簡單。問題是這樣做將需要連接事件爲項目,該事件在某種程度上顯示了第二ContextMenuStrip將關閉當前的ContextMenuStrip(即使我們增加一些Closing事件處理程序,並設置e.Cancel = true;)。這裏有點棘手。我們可以想象當前ContextMenuStripMouseDown事件,但事實上這個事件很難被解僱,因爲所有的項目都位於ContextMenuStrip之上。這讓我想到了更深的階段,我們可以趕上WM_RBUTTONDOWN並在那裏運行代碼。我們可以自定義ContextMenuStrip以在WndProc中捕獲該消息,或者我們可以使用自定義NativeWindow。我想在這裏使用NativeWindow。這是時間碼(正常使用):

public class NativeContextMenuStrip : NativeWindow 
{ 
    public class ShowContextMenuEventArgs : EventArgs { 
     public ToolStripDropDown ContextMenuToShow {get; set;} 
    } 
    public delegate void ShowContextMenuEventHandler(ShowContextMenuEventArgs e); 
    public event ShowContextMenuEventHandler ShowContextMenu; 
    private Color previousItemBackColor; 
    public ToolStripItem SourceItem { get; set; } 
    bool keepOpen; 
    protected override void WndProc(ref Message m) 
    {      
     base.WndProc(ref m);    
     if (m.Msg == 0x204) {//WM_RBUTTONDOWN 
      OnShowContextMenu(new ShowContextMenuEventArgs()); 
     } 
    } 
    protected virtual void OnShowContextMenu(ShowContextMenuEventArgs e) 
    { 
     var handler = ShowContextMenu; 
     if (handler != null) 
     { 
      handler(e); 
      if (e.ContextMenuToShow != null) 
      { 
       ContextMenuStrip toolStrip = (ContextMenuStrip)Control.FromHandle(Handle); 
       Point client = toolStrip.PointToClient(Control.MousePosition); 
       SourceItem = toolStrip.GetItemAt(client); 
       previousItemBackColor = SourceItem.BackColor; 
       SourceItem.BackColor = SystemColors.MenuHighlight;      
       e.ContextMenuToShow.Closed -= restoreItemState; 
       e.ContextMenuToShow.Closed += restoreItemState; 
       keepOpen = true; 
       e.ContextMenuToShow.Show(Control.MousePosition); 
       keepOpen = false; 
      } 
     }     
    } 
    protected override void OnHandleChange() 
    { 
     base.OnHandleChange(); 
     ContextMenuStrip toolStrip = Control.FromHandle(Handle) as ContextMenuStrip; 
     if (toolStrip != null) 
     { 
      toolStrip.Closing += toolStripClosing; 
     } 
    } 
    private void restoreItemState(object sender, EventArgs e) 
    { 
     SourceItem.BackColor = previousItemBackColor; 
     SourceItem.Owner.Show(); 
    } 
    private void toolStripClosing(object sender, ToolStripDropDownClosingEventArgs e) 
    { 
     e.Cancel = keepOpen; 
    } 
} 

用法::最重要的事件是ShowContextMenu,掛鉤該事件並設置ContextMenuStrip你想顯示。就這樣。下面是詳細:

public partial class Form1 : Form { 
    public Form1(){ 
    InitializeComponent(); 
    //suppose you have a main ContextMenuStrip and a sub ContextMenuStrip 
    //try adding some items for both 
    ContextMenuStrip = new ContextMenuStrip(); 
    ContextMenuStrip.Items.Add("Item 1"); 
    ContextMenuStrip.Items.Add("Item 2"); 
    //sub ContextMenuStrip 
    var subMenu = new ContextMenuStrip(); 
    subMenu.Items.Add("Delete"); 
    subMenu.Items.Add("Rename"); 
    ContextMenuStrip.HandleCreated += (s,e) => { 
     nativeMenu.AssignHandle(ContextMenuStrip.Handle); 
     nativeMenu.ShowContextMenu += (ev) => { 
      ev.ContextMenuToShow = subMenu; 
     }; 
    }; 
    } 
    NativeContextMenuStrip nativeMenu = new NativeContextMenuStrip(); 
} 

爲了獲得該項目點擊足見其子ContextMenuStrip,您可以訪問NativeContextMenuStripSourceItem

enter image description here

相關問題