我想,當我點擊菜單項上,展示的物品,諸如「刪除」,「重命名」等如何的ContextMenuStrip添加到ToolStripMenuItem
如何把自己綁定一個上下文菜單時上下文菜單你右鍵單擊菜單項?
我想,當我點擊菜單項上,展示的物品,諸如「刪除」,「重命名」等如何的ContextMenuStrip添加到ToolStripMenuItem
如何把自己綁定一個上下文菜單時上下文菜單你右鍵單擊菜單項?
第一個跳躍在我腦海的想法是在ToolStripMenuItem
上掛上一些MouseDown
事件,並在屏幕座標中的鼠標位置顯示第二個ContextMenuStrip
。但並非如此簡單。問題是這樣做將需要連接事件爲每項目,該事件在某種程度上顯示了第二ContextMenuStrip
將關閉當前的ContextMenuStrip(即使我們增加一些Closing
事件處理程序,並設置e.Cancel = true;
)。這裏有點棘手。我們可以想象當前ContextMenuStrip
的MouseDown
事件,但事實上這個事件很難被解僱,因爲所有的項目都位於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
,您可以訪問NativeContextMenuStrip
的SourceItem
。
WPF or Winforms? –
您可以提供一個特殊的'ToolStripMenuItem' *編輯菜單*項目,打開對話框來編輯菜單的某個部分。 – Sinatr