In a WPF app I'm working on, there is a Button
Style
which defines it's own Template
(ControlTemplate
).
I handles visual updates via ControlTemplate.Triggers
, like the following for IsMouseOver
:
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="IsMouseOverBorder"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0.08" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="IsMouseOverBorder"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:0.16" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
I've added a context menu to some Button
s which use this style. Having done so, when right-clicking on a Button
, the context menu shows, but the IsMouseOver
trigger then immediately does it's Exit action. I would prefer that the IsMouseOver
visual state is maintained while the context menu is open – it would look much nicer.
How can I do this?
Here's a couple of additional triggers which I thought would achieve what I want, but it doesn't. The first trigger (ContextMenuOpening
) works, but the second trigger does not - the button is left in a permanent IsMouseOver
looking state.
<EventTrigger RoutedEvent="ContextMenuService.ContextMenuOpening">
<BeginStoryboard Name="ContextMenuOpeningStoryboard">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="IsMouseOverBorder"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="ContextMenuService.ContextMenuClosing">
<RemoveStoryboard BeginStoryboardName="ContextMenuOpeningStoryboard" />
</EventTrigger>
Any idea why this won't work, or an alternate method that would work?
I got this to work using the styles as defined in my question, but I had to manually raise the ContextMenuService.ContextMenuClosingEvent
event (using some reflection to do so):
<ContextMenu Closed="ContextMenu_Closed">...</ContextMenu>
Code behind:
private void ContextMenu_Closed(object sender, RoutedEventArgs args)
{
var type = typeof(ContextMenuEventArgs);
var contextMenuEventArgs = (ContextMenuEventArgs) type.Assembly.CreateInstance
(
type.FullName, false, BindingFlags.Instance | BindingFlags.NonPublic, null,
new object[] { this, false }, null, null
);
if (contextMenuEventArgs != null)
{
contextMenuEventArgs.RoutedEvent = ContextMenuService.ContextMenuClosingEvent;
_myToggleButton.RaiseEvent(contextMenuEventArgs);
}
}