Add actions to existing context menus

Discussions related to SoftPro Select user interface development.

Moderator: Phil Barton

Post Reply
chris.brady
Posts: 105
Joined: Wed Oct 17, 2012 4:20 pm

Add actions to existing context menus

Post by chris.brady »

We'd like to add a new item into the right-click context menu in the search results on the start page in Select. When a user searches for orders, they would right-click on an order in the results list to display the context menu (currently the default menu contains Open, History, Print Barcode), and select a new menu item we've added. Clicking this menu item would either execute some code we've written, or could display a sub-menu with additional sub menu items that each execute some code.

Specifically, in our case, we'd like to present a new "Complete Tasks" menu item, so if a user right-clicks on an order in the search results and select this item, it would present a sublist of incomplete checklist tasks to complete. When a user clicks on one of these tasks (or possibly another menu item "complete all"), our code would open the order they clicked on (or even multiple, assuming multi-select is allowed), mark whatever tasks we want to complete, and close the order.

Based on a quick conversation with John Morris via e-mail, it sounds like this is doable. We'd really appreciate if you could provide some sample code to show us how to hook into the menu system and read the search results to act on an order.

I've tried to upload a screenshot to avoid a lengthy explanation, but get an error "Could not upload attachment to ./files/174_f5e7e349cddcf03375ad445245152f48." when doing so (I have been getting this error for the past couple of years). If you need more details or clarification, please let me know.
John Morris
Posts: 411
Joined: Thu Sep 11, 2008 11:35 am
Location: Raleigh, NC, USA
Contact:

Re: Add actions to existing context menus

Post by John Morris »

This is totally doable! :-)

Just follow these steps.

1. You need to create a context menu group that extends the built-in context menu for ProForm search results. Each search results type has its own context menu identifier. In the case of Orders, you need the following added to your shell package CTD file.

Code: Select all

...
  <Symbols>

    <!-- These are your own menu items, so the GUIDs and IDs will vary -->
    <Guid name="CommandSetGuid1" value="8AF99BCA-C3FB-4FED-A0D8-065CB1978815">
      <ID name="MyGroup" value="0x0001" />
      <ID name="MyCommand" value="0x0002" />
    </Guid>


    <!-- These are the magic numbers for ProForm. These need to match exactly. -->
    <Guid name="ProFormCommandSet" value="F436331E-3D02-4B9B-AF76-FC878517BCF9">
      <ID name="ProFormSearchResultsMenu" value="1200" />
    </Guid>

  </Symbols>

  <Commands>

    <MenuRef id="ProFormSearchResultsMenu">
      <Group id="MyGroup" priority="100">
        <Button id="MyCommand" text="My Command" style="Dynamic" />
      </Group>
    </MenuRef>

  </Commands>
...
2. Next, you need to hook up to the newly added menu. This is typically done in your shell package's OnInitialize override.

Code: Select all

...
        /// <summary>
        /// Called when [initialize].
        /// </summary>
        protected override void OnInitialize()
        {
            //TODO: Provide package initialization logic here.
            this.RegisterHandler(MyPackage.MyCommand, MyCommand_Invoke, MyCommand_QueryStatus);
        }

        /// <summary>
        /// Handles the QueryStatus event of the MyCommand control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="QueryStatusEventArgs"/> instance containing the event data.</param>
        /// <exception cref="NotImplementedException"></exception>
        private void MyCommand_QueryStatus(object sender, QueryStatusEventArgs e)
        {
            IMonitorSelection monitor = GetService<IMonitorSelection>();
            ISelectionContainer selection = monitor.Selection;
            e.Enabled = (selection != null && selection.SelectedObjects.Length > 0);
        }

        /// <summary>
        /// Handles the Invoke event of the MyCommand control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="InvokeEventArgs"/> instance containing the event data.</param>
        /// <exception cref="NotImplementedException"></exception>
        private void MyCommand_Invoke(object sender, InvokeEventArgs e)
        {
            IMonitorSelection monitor = GetService<IMonitorSelection>();
            ISelectionContainer selection = monitor.Selection;
            if (selection != null)
            {
                ISearchResultRow row = (ISearchResultRow)selection.SelectedObjects.FirstOrDefault();
                if (row != null)
                {
                    MessageBox.Show(row[0].ToString()); //Index 0 is always the moniker (uri) in search results
                }
            }
        }
...
John Morris
Sr. Software Architect
SoftPro
Post Reply