2008-11-11 12 views
10

öğesini sağ tıklattığınızda İçerik Menüsü nasıl görüntülenir? .NET WinForms uygulamasına bir MFC uygulaması yerleştiriyorum. MFC uygulamasında, bir menüye veya bir içerik menüsü öğesine sağ tıklayabilir ve teşhis ve yapılandırma öğeleriyle başka bir bağlam menüsü gösterebiliriz. Bu işlevselliği .NET'e taşımaya çalışıyorum ama sorun yaşıyorum.Menü Öğesi

Sağ tıklamayı yakalayabildim, alttaki menünün tıklatılmasını devre dışı bıraktım ve doğru konumdaki bir içerik menüsü açtım, ancak orijinal menü odağı kaybettiğinde kaybolur. MFC

, biz TPM_RECURSE bayrağıyla TrackPopupMenuEx arayarak yeni bağlam menüsünü gösterir. .NET

ContextMenu ve daha yeni ContextMenuStrip sınıflar sadece yöntemini göster var. Bunu .NET'te nasıl yapacağını bilen var mı?

DÜZENLEME Ben çağırmak/a'dan p'ye kadar TrackPopupMenuExkullanarak denedi, ama bu bizim uygulamada yersiz görünen bir ContextMenuStrip yerine bir ContextMenu kullanmaya sınırlar

. Ayrıca hala düzgün çalışmıyor. Yeni MenuStrip ve ContextMenuStrip ile çalışmaz.

Ayrıca, bir içerik menüsü ekleyip ekleyemeyeceğimi görmek için alt sınıf ToolStripMenuItem'i denedim. MenuStrip için çalışıyor, ancak ContextMenuStrip hala sağ tıklama olaylarının tıklamalar olarak geçmesine izin veriyor.

+0

Neden menü öğesi üzerine geldiğinizde, daha fazla öğeleri gösterir, böylece sadece bir alt menüsünü kullanabilirsiniz? –

+0

Menülerin çoğunun zaten alt menüleri var. Yöneticiler için menüler güvenliğini ayarlamak için bu özelliği kullanırız. Örneğin, bir menüye sağ tıklayın ve devre dışı bırakılacak şekilde ayarlayın. Bu veritabanında saklanır ve tüm kullanıcılar için etkilenir. –

cevap

10

Düzenleme:

yılında:

MouseButtons != MouseButtons.Right 

gerektiği ve Control.MouseButtons yapılan bir çağrı olduğu gibi derliyor

protected override void OnClick(EventArgs e) 
{ 
    if (SecondaryContextMenu == null || MouseButtons != MouseButtons.Right) 
    { 
     base.OnClick(e); 
    } 
} 

bu bölüm. Form, Control sınıfını devraldığından, MouseButtons özelliğini doğrudan aramak yeterlidir.

Umut bu yardımcı olur:

public partial class Form1 : Form 
{ 
    class CustomToolStripMenuItem : ToolStripMenuItem 
    { 
     private ContextMenuStrip secondaryContextMenu; 

     public ContextMenuStrip SecondaryContextMenu 
     { 
      get 
      { 
       return secondaryContextMenu; 
      } 
      set 
      { 
       secondaryContextMenu = value; 
      } 
     } 

     public CustomToolStripMenuItem(string text) 
      : base(text) 
     { } 

     protected override void Dispose(bool disposing) 
     { 
      if (disposing) 
      { 
       if (secondaryContextMenu != null) 
       { 
        secondaryContextMenu.Dispose(); 
        secondaryContextMenu = null; 
       } 
      } 

      base.Dispose(disposing); 
     } 

     protected override void OnClick(EventArgs e) 
     { 
      if (SecondaryContextMenu == null || MouseButtons != MouseButtons.Right) 
      { 
       base.OnClick(e); 
      } 
     } 
    } 

    class CustomContextMenuStrip : ContextMenuStrip 
    { 
     private bool secondaryContextMenuActive = false; 
     private ContextMenuStrip lastShownSecondaryContextMenu = null; 

     protected override void Dispose(bool disposing) 
     { 
      if (disposing) 
      { 
       if (lastShownSecondaryContextMenu != null) 
       { 
        lastShownSecondaryContextMenu.Close(); 
        lastShownSecondaryContextMenu = null; 
       } 
      } 
      base.Dispose(disposing); 
     } 

     protected override void OnControlAdded(ControlEventArgs e) 
     { 
      e.Control.MouseClick += new MouseEventHandler(Control_MouseClick); 
      base.OnControlAdded(e); 
     } 

     protected override void OnControlRemoved(ControlEventArgs e) 
     { 
      e.Control.MouseClick -= new MouseEventHandler(Control_MouseClick); 
      base.OnControlRemoved(e); 
     } 

     private void Control_MouseClick(object sender, MouseEventArgs e) 
     { 
      ShowSecondaryContextMenu(e); 
     } 

     protected override void OnMouseClick(MouseEventArgs e) 
     { 
      ShowSecondaryContextMenu(e); 
      base.OnMouseClick(e); 
     } 

     private bool ShowSecondaryContextMenu(MouseEventArgs e) 
     { 
      CustomToolStripMenuItem ctsm = this.GetItemAt(e.Location) as CustomToolStripMenuItem; 

      if (ctsm == null || ctsm.SecondaryContextMenu == null || e.Button != MouseButtons.Right) 
      { 
       return false; 
      } 

      lastShownSecondaryContextMenu = ctsm.SecondaryContextMenu; 
      secondaryContextMenuActive = true; 
      ctsm.SecondaryContextMenu.Closed += new ToolStripDropDownClosedEventHandler(SecondaryContextMenu_Closed); 
      ctsm.SecondaryContextMenu.Show(Cursor.Position); 
      return true; 
     } 

     void SecondaryContextMenu_Closed(object sender, ToolStripDropDownClosedEventArgs e) 
     { 
      ((ContextMenuStrip)sender).Closed -= new ToolStripDropDownClosedEventHandler(SecondaryContextMenu_Closed); 
      lastShownSecondaryContextMenu = null; 
      secondaryContextMenuActive = false; 
      Focus(); 
     } 

     protected override void OnClosing(ToolStripDropDownClosingEventArgs e) 
     { 
      if (secondaryContextMenuActive) 
      { 
       e.Cancel = true; 
      } 

      base.OnClosing(e); 
     } 
    } 

    public Form1() 
    { 
     InitializeComponent(); 


     CustomToolStripMenuItem itemPrimary1 = new CustomToolStripMenuItem("item primary 1"); 
     itemPrimary1.SecondaryContextMenu = new ContextMenuStrip(); 
     itemPrimary1.SecondaryContextMenu.Items.AddRange(new ToolStripMenuItem[] { 
      new ToolStripMenuItem("item primary 1.1"), 
      new ToolStripMenuItem("item primary 1.2"), 
     }); 

     CustomToolStripMenuItem itemPrimary2 = new CustomToolStripMenuItem("item primary 2"); 
     itemPrimary2.DropDownItems.Add("item primary 2, sub 1"); 
     itemPrimary2.DropDownItems.Add("item primary 2, sub 2"); 
     itemPrimary2.SecondaryContextMenu = new ContextMenuStrip(); 
     itemPrimary2.SecondaryContextMenu.Items.AddRange(new ToolStripMenuItem[] { 
      new ToolStripMenuItem("item primary 2.1"), 
      new ToolStripMenuItem("item primary 2.2"), 
     }); 

     CustomContextMenuStrip primaryContextMenu = new CustomContextMenuStrip(); 
     primaryContextMenu.Items.AddRange(new ToolStripItem[]{ 
      itemPrimary1, 
      itemPrimary2 
     }); 

     this.ContextMenuStrip = primaryContextMenu; 
    } 
} 
+0

Bunu deneyeceğim, teşekkürler. –

+0

Teşekkürler, bu ContextMenuStrip için çalışıyor ve bir MenuStrip üst düzey menüler için değiştirildi. Hala MenuStrip'in alt menüleri için çalışmaya başlayamıyorum, ama bunun sadece GetItemAt çağrısı ile ilgili bir sorun olduğunu düşünüyorum. –

+0

CustomToolstripMenuItem sınıfındaki OnClick geçersiz kılmaları derlenmez. Olamaz (MouseButtons! = MouseButtons.Right). Bu çizgi ne olmalı? Hangi düğmeye basıldığını, tıklama olayı nasıl belirlersiniz. –

2

Muhtemelen yöntemi çağırmanız/çağırmanız gerekecektir. nedeniyle bir yoruma

[DllImport("user32.dll")] 
static extern bool TrackPopupMenuEx(IntPtr hmenu, uint fuFlags, int x, int y, 
IntPtr hwnd, IntPtr lptpm); 

const int TPM_RECURSE = 0x0001; 
+0

Şimdiye kadar bu çalışmayı başaramadım. –

+0

Bu kısmen ContextMenuStrip ile değil, eski ContextMenu ile çalıştım. O zaman bile, odaklama ve vurgulama ile ilgili bazı problemler yaşıyordu, ayrıca eski ContextMenu sınıfları daha yeni menülerle doğru görünmüyordu. –