Bring up ContextMenu when IsMouseOver on a Button using only XAML

4.7k views Asked by At

I am trying to use XAML (only, no codebehind) to bring up the ContextMenu of a button.

I have this my button here

<Button x:Name="btn" Style="{StaticResource mybutton}" >
<Button.ContextMenu>
    <ContextMenu>
        <TextBlock Text="Information"/>
    </ContextMenu>
</Button.ContextMenu>
</Button>

The Style for the button here

<Style TargetType="{x:Type Button}" x:Key="mybutton">
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type Button}">
            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="ContextMenu.IsOpen" Value="True"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Setter.Value>
</Setter>
</Style>

My google-fu is failing me for what seems like an easy solution. I really would prefer to avoid using codebehind (MouseEnter/MouseLeave events).

Thank you in advance.

3

There are 3 answers

1
makagonov On BEST ANSWER

Try to apply "Setter" for a ContextMenu within the ControlTemplate, by providing it's name in the "TargetName" property. For example:

<Button Width="100" Height="100" x:Name="btn">
        <Button.Style>
            <Style TargetType="Button">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Border CornerRadius="2" BorderThickness="3" BorderBrush="DarkGray" x:Name="border">
                                <Border.ContextMenu>
                                    <ContextMenu x:Name="cmenu">
                                        <TextBlock>Information</TextBlock>
                                    </ContextMenu>
                                </Border.ContextMenu>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="ContextMenu.IsOpen" Value="True" TargetName="cmenu"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Button.Style>
1
Rohit Vats On

This is what you want i guess - http://social.msdn.microsoft.com/forums/en-US/wpf/thread/adafe007-9637-4f28-8366-8f14ead2bd75

All you need to do is capture the mouse event that you want to trigger the context menu.
0
DrMarbuse On

It is best to use a mouse_up event in codebehind. With MouseOver the user feels fooled as the context menu is gone when the mouse moves towards an entry... In VB the code looks like:

Private Sub image_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles image.MouseUp
    anyControl.ContextMenu.IsOpen = Not OrteListBox.ContextMenu.IsOpen
End Sub

anyCountrol stands for the sender or any other control that holds the ContextMenu