2010-08-07 1 views
2

Je n'ai pas réussi à comprendre comment garder un menu contextuel ouvert après avoir géré un événement de clic après le premier niveau. Voici un exemple où j'ai un menu contextuel avec un menu de menus vérifiables. J'ouvre le menu contextuel après avoir manipulé l'événement de clic, mais je dois retourner manuellement au menu intérieur. Existe-t-il un moyen d'ouvrir le menu externe par programme ou d'empêcher le menu interne de se fermer?ContextMenu ne restera pas ouvert C# .Net 4.0 Profil du client WinForms

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace NoCloseContextMenu 
{ 
    public partial class Form1 : Form 
    { 
     bool[] store_checks = new bool[8]; 

     public Form1() 
     { 
      InitializeComponent(); 
      richTextBox1.AppendText("http://"); 
      richTextBox1.LinkClicked += new LinkClickedEventHandler(richTextBox1_LinkClicked); 
     } 

     void richTextBox1_LinkClicked(object sender, LinkClickedEventArgs e) 
     { 
      MenuItemExtended[] inner_menuitems = new MenuItemExtended[8]; 
      for (int i = 0; i < store_checks.Length; i++) 
      { 
       MenuItemExtended inner_menuitem = new MenuItemExtended("Check #" + i.ToString()); 
       inner_menuitem.menuitem_index = i; 
       inner_menuitem.contextmenu_point = this.PointToClient(Cursor.Position); 
       inner_menuitem.Checked = store_checks[i]; 
       inner_menuitem.Shortcut = (Shortcut)(131120 + i); //Ctrl+i = 131120+i 
       inner_menuitem.ShowShortcut = true; 
       inner_menuitem.Click += new EventHandler(inner_menuitem_Click); 
       inner_menuitems[i] = inner_menuitem; 
      } 
      MenuItem outer_menu = new MenuItem("Outer Menu", inner_menuitems); 
      ContextMenu context_menu = new ContextMenu(new MenuItem[] { outer_menu }); 
      context_menu.Show(this, this.PointToClient(Cursor.Position)); 
     } 

     void inner_menuitem_Click(object sender, EventArgs e) 
     { 
      MenuItemExtended sender_menu = (MenuItemExtended)sender; 
      store_checks[sender_menu.menuitem_index] = !store_checks[sender_menu.menuitem_index]; 
      sender_menu.Checked = !sender_menu.Checked; 
      sender_menu.GetContextMenu().Show(this, sender_menu.contextmenu_point); 
     } 

     /// <summary> 
     /// Required designer variable. 
     /// </summary> 
     private System.ComponentModel.IContainer components = null; 

     /// <summary> 
     /// Clean up any resources being used. 
     /// </summary> 
     /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
     protected override void Dispose(bool disposing) 
     { 
      if (disposing && (components != null)) 
      { 
       components.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     #region Windows Form Designer generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InitializeComponent() 
     { 
      this.richTextBox1 = new System.Windows.Forms.RichTextBox(); 
      this.SuspendLayout(); 
      // 
      // richTextBox1 
      // 
      this.richTextBox1.Location = new System.Drawing.Point(13, 13); 
      this.richTextBox1.Name = "richTextBox1"; 
      this.richTextBox1.Size = new System.Drawing.Size(100, 96); 
      this.richTextBox1.TabIndex = 0; 
      this.richTextBox1.Text = ""; 
      // 
      // Form1 
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
      this.ClientSize = new System.Drawing.Size(284, 262); 
      this.Controls.Add(this.richTextBox1); 
      this.Name = "Form1"; 
      this.Text = "Form1"; 
      this.ResumeLayout(false); 

     } 

     #endregion 

     private System.Windows.Forms.RichTextBox richTextBox1; 
    } 

    public class MenuItemExtended : MenuItem 
    { 
     public int menuitem_index; 
     public Point contextmenu_point; 

     public MenuItemExtended(string text) 
     { 
      this.Text = text; 
     } 
    } 
} 

Aussi, est-il possible d'obtenir les raccourcis « Ctrl + numéro » pour travailler et activer l'événement click? Merci d'avance pour l'aide!

Répondre

0

Je n'ai trouvé aucun moyen d'empêcher la fermeture du menu contextuel. À la place, j'ai utilisé ContextMenuStrip et ToolStripMenuItem. Cela a également résolu le problème que j'avais avec les raccourcis qui ne fonctionnaient pas auparavant. Je gère l'événement Closing du menu contenant les éléments vérifiables et annule la fermeture si les éléments ont été cliqués/cochés.

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace NoCloseContextMenu 
{ 
    public partial class Form1 : Form 
    { 
     bool[] store_checks = new bool[8]; 

     public Form1() 
     { 
      InitializeComponent(); 
      richTextBox1.AppendText("http://"); 
      richTextBox1.LinkClicked += new LinkClickedEventHandler(richTextBox1_LinkClicked); 
     } 

     void richTextBox1_LinkClicked(object sender, LinkClickedEventArgs e) 
     { 
      ToolStripMenuItem[] inner_menuitems = new ToolStripMenuItem[8]; 
      for (int i = 0; i < store_checks.Length; i++) 
      { 
       ToolStripMenuItem inner_menuitem = new ToolStripMenuItem("Check #" + i.ToString()); 
       inner_menuitem.Checked = store_checks[i]; 
       inner_menuitem.CheckOnClick = true; 
       inner_menuitem.ShortcutKeys = Keys.Control | (Keys)(48 + i); //Di = 48 + i 
       inner_menuitem.ShowShortcutKeys = true; 
       inner_menuitem.Click += new EventHandler(inner_menuitem_Click); 
       inner_menuitem.Tag = i.ToString(); 
       inner_menuitems[i] = inner_menuitem; 
      } 
      ToolStripMenuItem outer_menu = new ToolStripMenuItem("Outer Menu", null, inner_menuitems); 
      outer_menu.DropDown.Closing += new ToolStripDropDownClosingEventHandler(DropDown_Closing); 
      ContextMenuStrip context_menu = new ContextMenuStrip(); 
      context_menu.Items.Add(outer_menu); 
      context_menu.Show(this, this.PointToClient(Cursor.Position)); 
     } 

     void DropDown_Closing(object sender, ToolStripDropDownClosingEventArgs e) 
     { 
      if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked) 
      { 
       e.Cancel = true; 
       ((ToolStripDropDownMenu)sender).Invalidate(); 
      } 
     } 

     void inner_menuitem_Click(object sender, EventArgs e) 
     { 
      ToolStripMenuItem sender_menu = (ToolStripMenuItem)sender; 
      int index = int.Parse(sender_menu.Tag.ToString()); 
      store_checks[index] = !store_checks[index]; 
     } 

     /// <summary> 
     /// Required designer variable. 
     /// </summary> 
     private System.ComponentModel.IContainer components = null; 

     /// <summary> 
     /// Clean up any resources being used. 
     /// </summary> 
     /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
     protected override void Dispose(bool disposing) 
     { 
      if (disposing && (components != null)) 
      { 
       components.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     #region Windows Form Designer generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InitializeComponent() 
     { 
      this.richTextBox1 = new System.Windows.Forms.RichTextBox(); 
      this.SuspendLayout(); 
      // 
      // richTextBox1 
      // 
      this.richTextBox1.Location = new System.Drawing.Point(13, 13); 
      this.richTextBox1.Name = "richTextBox1"; 
      this.richTextBox1.Size = new System.Drawing.Size(100, 96); 
      this.richTextBox1.TabIndex = 0; 
      this.richTextBox1.Text = ""; 
      // 
      // Form1 
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
      this.ClientSize = new System.Drawing.Size(284, 262); 
      this.Controls.Add(this.richTextBox1); 
      this.Name = "Form1"; 
      this.Text = "Form1"; 
      this.ResumeLayout(false); 
     } 

     #endregion 

     private System.Windows.Forms.RichTextBox richTextBox1; 
    } 
} 

Vous pouvez également sélectionner certains boutons dans votre sous-menu non fermable pour que le menu contextuel se ferme normalement. Pour une ToolStripMenuItem spécifique pour fermer le menu normalement, lui donner une méthode d'événement différent pour appeler:

inner_menuitem.Click += new EventHandler(inner_menuitem_Can_Close); 

Et utiliser le code suivant dans la méthode (fonctionne quelle que soit la profondeur des menus aller):

void inner_menuitem_Can_Close(object sender, EventArgs e) 
{ 
    ToolStripMenuItem castSender = (ToolStripMenuItem)sender; 
    object owner = castSender.OwnerItem; 
    while (owner is ToolStripMenuItem) 
    { 
     if (((ToolStripMenuItem)owner).Owner is ContextMenuStrip) 
      ((ContextMenuStrip)((ToolStripMenuItem)owner).Owner).Close(); 
     owner = ((ToolStripMenuItem)owner).OwnerItem; 
    } 
} 
0

Je vous déconseille fortement de gérer les événements de clic sur les éléments de menu contextuel 'parent' - laissez le système d'exploitation gérer cela pour vous.

Questions connexes