How can I tell a ContextMenu to place itself relatively to its control and not the cursor?

10,462

Check out Remarks under ContextMenu.Placement

and try this

<Button Content="Do this" Height="23" Width="75" 
     ContextMenuService.Placement="Bottom"
     Command="local:MyCommands.ThisCommand">
    <Button.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Do this" Command="local:MyCommands.ThisCommand" />
            <MenuItem Header="Do that" Command="local:MyCommands.ThatCommand" />
        </ContextMenu>
    </Button.ContextMenu>
</Button>
Share:
10,462

Related videos on Youtube

BoltClock
Author by

BoltClock

My pronouns are they/them. Learn more. Curious about my profile picture? Check out my Flash game on Newgrounds! I'm a software developer who relishes authoring HTML and CSS on the web and hacking C# on their self-built Windows PC. I adore Jesus and the colors green, purple and teal, and I often catch myself thinking in numbers and code on a whim. I was also a Microsoft MVP from 2017 through 2020. My areas of specialty are in web design — I've known HTML and CSS for more than a decade now! — and Windows app development with C# and XAML. Other languages I've worked with include (from most to least experience) PHP, SQL, ActionScript, Swift, Objective-C, Perl, Python, and Java. Roles on this site From the tags I participate in (below) as well as my bio (above), it's easy to tell that I'm interested in a number of languages and topics. However, you'll most often find me patrolling, curating and moderating the following tags: htmlcsscss-selectorsinternet-explorermicrosoft-edge As a moderator, I believe I am more efficient than ever with post revisions and other housekeeping duties, as I continue with my question-answering business. While I actively add fresh content to the site, I'm also helping out with cleaning and polishing our currently-existing posts. "Dust tends to settle", and all that jazz. Achievements Singapore's top user by reputation and first community moderator ♦ on Stack Overflow! 1st user to earn the bronze, silver and gold css-selectors badges! 4th user to earn the gold css badge! 9th user to earn the gold html badge! 45th user to earn the Legendary badge! 54th user to reach the 100,000-reputation milestone!

Updated on October 22, 2020

Comments

  • BoltClock
    BoltClock over 3 years

    I have a button with a default command and a context menu for other available commands:

    <Button Content="Do this" Height="23" Width="75" Command="local:MyCommands.ThisCommand">
        <Button.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Do this" Command="local:MyCommands.ThisCommand" />
                <MenuItem Header="Do that" Command="local:MyCommands.ThatCommand" />
            </ContextMenu>
        </Button.ContextMenu>
    </Button>
    

    By default, the context menu appears starting at the hot spot of the cursor:

    However, I'd like it to appear at a fixed relative position, beneath the button (fake, edited screenshot):

    Setting the context menu's Placement, PlacementRectangle and PlacementTarget properties doesn't seem to do anything; the context menu insists on hanging off the cursor wherever I right-click my button. Worse, focusing the button and hitting the menu key causes the context menu to sit in front of the button, blocking it completely.

    So, how exactly do I specify that the context menu should appear beneath the button?

  • BoltClock
    BoltClock about 13 years
    Thanks. Do you know why setting Placement on the ContextMenu doesn't work?
  • Bala R
    Bala R about 13 years
    @BoltClock I'm not sure. But check out the Remarks section of ContextMenu.Placement which states to set ContextMenuService.Placement
  • BoltClock
    BoltClock about 13 years
    The Remarks section happens to have the answer: "When the ContextMenu is assigned to the FrameworkElement.ContextMenu or FrameworkContentElement.ContextMenu property, the ContextMenuService changes this value of this property when the ContextMenu opens." Now everything falls into place.