AnsweredAssumed Answered

Best way to customize a ContextMenuStrip from AFTreeView

Question asked by fabiano.batista on Dec 16, 2014
Latest reply on Dec 16, 2014 by fabiano.batista

Hi folks,

 

I am trying to hide some items from a AFTreeView.ContextMenuStrip, since they will not needed in my application, and to add add a new Proprietary item . Here some of the code I copied from the AFUIRef help file:

 // Used for proprietary menu items.
        private const int kMenuStart = 0x3000;
         // An example of a proprietary menu option.
        private const int kMenuCommandProprietary = kMenuStart + 1;

 

This was added to the form designer...

this.afTreeView1.MenuItemClicked += new OSIsoft.AF.UI.MenuItemClickedEventHandler(this.afTreeView1_MenuItemClicked);

 

...add this is the sub called by the event handler above:

 private void afTreeView1_MenuItemClicked(object sender, MenuItemClickedEventArgs e)
        {
           // Get the AF menu from the AF tree view.
           AFMenu afmenu = afTreeView1.ContextMenuStrip as AFMenu;
            if (afmenu == null) return;

            try
            {
                // Override the properties selection and display the dialog as read-only.
                if ((AFMenu.MenuCommand)e.ClickedItem.MergeIndex == AFMenu.MenuCommand.Properties)
                {
                    // Display the wait cursor.
                    this.Cursor = Cursors.WaitCursor;

                    // Indicate to the caller that this click is handled.
                    e.Handled = true;

                    // Show the properties read-only using the AFOperations method.
                    bool readOnly = true;
                    AFOperations.ShowProperties(this, afmenu.AFObject, afmenu.AFContext, afmenu.AFPath, afmenu.AFFilter, readOnly);
                }
                else if (e.ClickedItem.MergeIndex == kMenuCommandProprietary)
                {
                    // Display the wait cursor.
                    this.Cursor = Cursors.WaitCursor;

                    // Indicate to the caller that this click is handled.
                    e.Handled = true;

                    MessageBox.Show(this, "This is a proprietary menu item selection", "My menu item");
                }
            }
            finally
            {
                // Restore the default cursor.
                this.Cursor = Cursors.Default;
            }

        }







 

I also added the event handlers as per example provided in the help file, and slightly modified the afmenu_Opened to hide the items I don't want to show:

 

// Add event handlers for the AF menu object uses as the AF tree view's context menu strip.
           // Use these events to override visibility, to disable an item, add a menu item, or handle the item clicked.
                       
            AFMenu afmenu = afTreeView1.ContextMenuStrip as AFMenu;
            //afmenu.Items.
            if (afmenu != null)
            {
                // Event raised before menu control is opening.
                afmenu.BeforeOpening += new CancelEventHandler(afmenu_BeforeOpening);
                // Event raised when the menu control is opening.
                afmenu.Opening += new CancelEventHandler(afmenu_Opening);
                // Event raised when the menu is opened.
               afmenu.Opened += new EventHandler(afmenu_Opened);
            }

// Event raised when the menu control is opening.
        void afmenu_Opening(object sender, CancelEventArgs e)
         {
            // Get the AF menu.
            AFMenu afmenu = sender as AFMenu;
            if (afmenu != null)
            {
                // Add your item to the menu if it doesn't already exist.
                ToolStripMenuItem item = afmenu.FindMenuItem((AFMenu.MenuCommand)kMenuCommandProprietary);
                if (item != null) return;

                // First add a separator.
                afmenu.AddSeparator();
                // Create a menu item.
                ToolStripMenuItem test = new ToolStripMenuItem("&Proprietary");
                test.MergeIndex = kMenuCommandProprietary;
                // Then the menu item.
                afmenu.Items.Add(test);
            }
        }

        // Event raised when the menu is opened.
        void afmenu_Opened(object sender, EventArgs e)
        {
            // Get the AF menu.
            AFMenu afmenu = sender as AFMenu;
            if (afmenu != null)
            {
                // Iterate through the menu to show the tool strip menu items.
                System.Diagnostics.Debug.WriteLine("  List of items in menu:");
                for (int ii = 0; ii < afmenu.Items.Count; ii++)
                {
                    ToolStripMenuItem item = afmenu.Items[ii] as ToolStripMenuItem;
                    if (item == null) continue;

                    // Use the text from the menu item directly.
                    System.Diagnostics.Debug.WriteLine("      menuText = " + item.Text + "; Index = " + item.MergeIndex.ToString());
                    if (afmenu.Items[ii].MergeIndex < kMenuCommandProprietary)
                    {
                        //afmenu.Items[ii].Enabled = false;
                     
                        afmenu.Items[ii].Visible = false;
                    }
                }
            }
        }

 

This is the result I get when I right click on my AFTreeView:

 

TreeViewSeparators.png

 

My question is: how to get rid of these many separators?

 

By the way, I also tried to call afmenu.Items[ii].Dispose() instead of afmenu.Items[ii].Visible = false, but some of the items cannot be removed. This is what I got:

 

TreeViewSeparators2.png

 

I assume these items don't have a Dispose() method implemented.

 

I also tried to dispose the entire ContextMenuStrip and create a new one, but then the eventhandlers did not trigger any action. The easiest solution would then to simply hide the items not needed, but I still would have to be able to delete the various separators.

 

If you have any ideas, please let me know.

 

Best regards

 

Fabiano Batista

Outcomes