Problem with Button template and properties IsMouseOver, IsPressed

Hello all,

I'm trying to implement some "standard" behavior of a button control. Let's take Win XP window minimize button for example. It has 3 states - Normal, MouseOver and MousePressed. If I click on minimize button and move mouse outside the button keeping left mouse button pressed, minimize button returns to the Normal state.

Question is how to achieve similar functionality with button template in xaml

All examples found in the internet behave this way: if mouse click is performed on some target button and mouse is moved outside the button keeping left mouse button pressed, target button returns to MouseOver state - not Normal.

A little example to illustrate WPF button behavior:

<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>

<ControlTemplate x:Key="MyButtonTemplate" TargetType="{x:Type Button}">
<Grid x:Name="_MainGrid">
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsMouseOver" Value="False">
<Setter TargetName="_MainGrid" Property="Background" Value="Silver"/>
</Trigger>
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter TargetName="_MainGrid" Property="Background" Value="Red"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Button.IsPressed" Value="True"/>
<Condition Property="Button.IsMouseOver" Value="True"/>
</MultiTrigger.Conditions>
<Setter TargetName="_MainGrid" Property="Background" Value="Blue"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>

</Page.Resources>
<Grid>

<Button Template="{StaticResource MyButtonTemplate}"/>

</Grid>
</Page>

In this example I would expect seeing Silver background instead of Red when the mouse is moved out of the window button also having left mouse button pressed.

Thanks,
Saulius



Answer this question

Problem with Button template and properties IsMouseOver, IsPressed

  • Radamante

    Hi Saulius,
    Here's what happens :

    • When the MultiTrigger kicks in, the current value of the background is saved (Red) and the new value is set (Blue). The mouse is also captured by the button (click event).
    • When the mouse leaves the button, the MultiTrigger conditions aren't met and the background is restored to the saved state (Red). Since the mouse is capture when the button is clicked, the MouseLeave event isn't raised and the IsMouseOver stays to True. The MouseLeave will be raised when you release the mouse button and the button will release capture of the mouse.

    Here's a small sample which will show you le capture/release of the mouse :

    <Button xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Button.Background>
    <SolidColorBrush x:Name="bgcolor" Color="Silver"/>
    </Button.Background>
    <Button.Triggers>
    <EventTrigger RoutedEvent="Button.MouseEnter">
    <BeginStoryboard>
    <Storyboard>
    <ColorAnimation Storyboard.TargetName="bgcolor" Storyboard.TargetProperty="Color" To="Red" Duration="0:0:0"/>
    </Storyboard>
    </BeginStoryboard>
    </EventTrigger>
    <EventTrigger RoutedEvent="Button.MouseLeave">
    <BeginStoryboard>
    <Storyboard>
    <ColorAnimation Storyboard.TargetName="bgcolor" Storyboard.TargetProperty="Color" To="Silver" Duration="0:0:0"/>
    </Storyboard>
    </BeginStoryboard>
    </EventTrigger>
    </Button.Triggers>
    </Button>

    Mouse over the button, click without release and move the mouse out. The color won't change. Release the button, the color will change.

    Guillaume


  • nonno

    Thanks Guillaume for Your post but it did not solve my problem.

    It works the same way as previous example on my PC, the only difference I see is that Your button has only 2 states at all. I tried adding one more trigger to Your example - MouseDown, but it does not work either.

    Any other suggestions are welcome.

    Again my problem: how would I implement 3 state button that would return to Normal (not to MouseOver) state after moving mouse off the button and having left mouse button pressed


  • toddw07

    After playing a bit more... My little sample of 3 state "old style" button:

    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
    <ControlTemplate x:Key="MyButtonTemplate" TargetType="{x:Type Control}">
    <Grid x:Name="_MainGrid">
    <Grid.Background>
    <SolidColorBrush x:Name="bgcolor" Color="Silver"/>
    </Grid.Background>
    </Grid>
    <ControlTemplate.Triggers>
    <EventTrigger RoutedEvent="Button.MouseEnter">
    <BeginStoryboard>
    <Storyboard>
    <ColorAnimation Storyboard.TargetName="bgcolor" Storyboard.TargetProperty="Color" To="Red" Duration="0:0:0"/>
    </Storyboard>
    </BeginStoryboard>
    </EventTrigger>
    <EventTrigger RoutedEvent="Button.MouseDown">
    <BeginStoryboard>
    <Storyboard>
    <ColorAnimation Storyboard.TargetName="bgcolor" Storyboard.TargetProperty="Color" To="Black" Duration="0:0:0"/>
    </Storyboard>
    </BeginStoryboard>
    </EventTrigger>
    <EventTrigger RoutedEvent="Button.MouseUp">
    <BeginStoryboard>
    <Storyboard>
    <ColorAnimation Storyboard.TargetName="bgcolor" Storyboard.TargetProperty="Color" To="Red" Duration="0:0:0"/>
    </Storyboard>
    </BeginStoryboard>
    </EventTrigger>
    <EventTrigger RoutedEvent="Button.MouseLeave">
    <BeginStoryboard>
    <Storyboard>
    <ColorAnimation Storyboard.TargetName="bgcolor" Storyboard.TargetProperty="Color" To="Silver" Duration="0:0:0"/>
    </Storyboard>
    </BeginStoryboard>
    </EventTrigger>
    </ControlTemplate.Triggers>
    </ControlTemplate>
    </Page.Resources>
    <Grid>
    <Control Template="{StaticResource MyButtonTemplate}"/>
    </Grid>
    </Page>


  • Problem with Button template and properties IsMouseOver, IsPressed