Have you ever looked at the standard Dynamics 365 Finance & Operations navigation pane and thought, "Wow, our users really love scrolling through fifty-seven menu items they don't have permission, configuration, or any earthly reason to use"?
No? Neither has anyone else.
Normally, we manage what users see using security roles or standard configuration keys. But what happens when you need to hide or show a menu item based on complex, runtime business logic? For example: “Only show this custom menu item if it’s a Tuesday, the customer’s credit rating is ‘Gold’, and the user has had their morning coffee.”
Today, we are diving deep into the metadata layer of X++ to intercept how D365 builds its menu tree. We will look at how to cleanly extend `MenuElementNode` and `MenuItemReferenceNode` to gain absolute power over what stays and what goes.
The Core Concept: Understanding the Tree
When D365 renders a module menu (like the SalesAndMarketing menu shown below), it evaluates a tree structure of metadata objects.
To control visibility dynamically, we have two primary hooks:
- `MenuElementNode`: The base class for structural components of the menu.
- `MenuItemReferenceNode`: The specific leaf node that points directly to an actual display, output, or action menu item.
By utilizing Chain of Command (CoC) on these nodes, we can intercept the standard `IsVisible()` method, perform our custom calculations, and cleanly return `true` or `false`.
🛠️ The Blueprints: Implementation Classes
Let's look at the implementation strategy using two targeted extensions.
1. The Generic Hook: Extending `MenuElementNode`
This extension targets the general structural element of the menu tree. It gives you a clean entry point to apply global visibility overrides.
2. The Smart Hook: Extending MenuItemReferenceNode
This is where the real magic happens. This extension evaluates specific menu items. In this example, the code dynamically checks if the menu item is linked to a specific Feature Class, and verifies its status programmatically via reflection (DictClass).
💡 Real-World Scenario: The VIP Clearance Toggle
Let’s bring this down to earth with a concrete example. Imagine your company has an exclusive menu item called `VIPDiscountConsole` inside the PricesAndDiscounts submenu.
You want this menu item to be visible only if:
1. The legal entity has the "VIP Toggling Feature" turned on in parameters.
2. The current user belongs to a specific User Group (`VIP_Managers`).
Instead of writing complex, hard-to-maintain security policies, your `hpIsVisible` method can look directly at a configuration class:
⚠️ A Note on Performance
Because `IsVisible()` is called frequently when menus load, keep your code fast and lightweight inside these extensions:
- ❌ Do not write heavy database queries (`select sum(Amount) from CustTrans...`).
- ❌ Do not make web service calls to external systems inside this loop.
- Do use caching strategies or read from pre-loaded global variables/singleton parameters. (Want to deep dive into caching? If you want to learn how to properly handle caching and prevent your code from hammering the database thousands of times in loops, check out my previous blog post: The Day My Code Called the Database 5000 Times (And How One Cache Fixed It). )
Summary
By extending `MenuElementNode` and `MenuItemReferenceNode`, you elevate control from static security settings to smart, context-aware user interfaces. This keeps workspace interfaces clean, precise, and streamlined for end-users.
Go forth and bend the UI to your will! After all, as developers, we hold the ultimate power: the ability to make our users' problems—and their menu items—vanish into thin air with a single line of code.
Keep your code clean, your caching fast, and remember: if you can control the menu, you can control the world. Now go declutter those workspaces and make the ERP world a slightly less chaotic place, one hidden button at a time!