1

我試圖創建一個ContextMenu,其中菜單中的某些項目包含多個單個項目。你可以看到它試圖結合ToolStrip和ContextMenuItem。 我試過使用ToolStripControlHost,但這會造成焦點問題。它基本上要求您點擊ToolStrip中的所有內容兩次。單個ContextMenuItem中的多個ToolStripButtons

ContextMenuStrip m = new ContextMenuStrip(); 
ToolStrip tStrip = new ToolStrip(new ToolStripDropDownButton(), new ToolStripButton()); 
ToolStripControlHost tsHost = new ToolStripControlHost(tStrip); 
m.Items.Add(tsHost); 

有關如何實現此目的的任何想法?

回答

1

ContextMenuStrip對於不像上下文菜單行爲的自定義彈出窗口的目標太吸引人了。這是可取的,因爲當用戶在菜單外單擊時它會自動彈出。儘管它有侷限性,但它不是一個很好的控制主機。點擊問題是經典問題,CMS捕獲鼠標以檢測用戶何時在窗口外點擊。

這真的應該是一種形式。爲了賦予它與CMS相同的行爲,需要一些工作。您必須檢測窗口外的鼠標點擊,以便讓窗口消失。像CMS一樣捕獲鼠標不起作用。一個竅門是使用IMessageFilter,它可以讓你在輸入消息被傳送到焦點窗口之前查看輸入消息。下面是一個實現此功能的示例窗體:

public partial class MyContextMenu : Form, IMessageFilter { 
    public MyContextMenu() { 
     InitializeComponent(); 
     Application.AddMessageFilter(this); 
    } 
    protected override void OnFormClosed(FormClosedEventArgs e) { 
     Application.RemoveMessageFilter(this); 
     base.OnFormClosed(e); 
    } 
    public void Show(Control ctl, Point pos) { 
     this.StartPosition = FormStartPosition.Manual; 
     this.Location = ctl.PointToScreen(pos); 
     while (!(ctl is Form)) ctl = ctl.Parent; 
     this.Show((Form)ctl); 
    } 
    public bool PreFilterMessage(ref Message m) { 
     // Detect mouse clicks outside of the form 
     if (m.Msg == 0x201 || m.Msg == 0x204 || m.Msg == 0x207 || 
      m.Msg == 0xA1 || m.Msg == 0xA4 || m.Msg == 0xA7) { 
      Point pos = new Point(m.LParam.ToInt32()); 
      Control ctl = Control.FromHandle(m.HWnd); 
      if (ctl != null) pos = ctl.PointToScreen(pos); 
      pos = this.PointToClient(pos); 
      if (pos.X < 0 || pos.Y < 0 || pos.X >= this.Width || pos.Y >= this.Height) { 
       this.Close(); 
      } 
     } 
     return false; 
    } 
} 

使用設計器作爲正常設計窗體。你至少想給它一個不同的FormBorderStyle。使用提供的Show()方法重載與使用CMS的方式相同。請注意,只有當您單擊應用程序所擁有的窗口時纔會彈出窗體,與CMS不同。功能,而不是一個錯誤。

+0

嗯是的,這可能會作爲一個開始。儘管我認爲在表單中模仿CMS的外觀和感覺會有很多工作。最後,CMS上的大多數項目仍然是普通的舊文本項目,可能還有圖像。 – PJanssen 2011-03-06 10:42:55

+0

它不會讓我編輯,因爲它沒有足夠的改變,但鼠標座標位於消息的'LParam'屬性而不是'WParam'。請參閱:http://msdn.microsoft.com/en-us/library/windows/desktop/ms645607%28v=vs.85%29.aspx – Anthony 2013-03-28 19:00:42