4

I am new to WPF animation.

I have a wpf application with 4 buttons. The 4 buttons have animations where the opacity of the button changes from 0.0 to 1.0 which gets triggered when the mouse hovers over that button.

The problem I am facing is that, even if the mouse slides over other buttons for a fraction of a second, the animations for those buttons are getting triggered.

Is there any way where I can trigger the animation only if the mouse stays on a button for a minimum of one second?

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="22.5*"/>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="22.5*"/>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="22.5*"/>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="22.5*"/>
        <ColumnDefinition Width="2*"/>
    </Grid.ColumnDefinitions>
    <Button x:Name="Button1" Grid.Column="1" Content="Button 1">
        <Button.Triggers>
            <EventTrigger RoutedEvent="Button.MouseEnter">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation From="0.0" To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Button1" Duration="0:0:1"></DoubleAnimation>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Button.Triggers>
    </Button>
    <Button x:Name="Button2" Grid.Column="3" Content="Button2">
        <Button.Triggers>
            <EventTrigger RoutedEvent="Button.MouseEnter">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation From="0.0" To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Button2" Duration="0:0:1"></DoubleAnimation>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Button.Triggers>
    </Button>
    <Button x:Name="Button3" Grid.Column="5" Content="Button 3">
        <Button.Triggers>
            <EventTrigger RoutedEvent="Button.MouseEnter">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation From="0.0" To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Button3" Duration="0:0:1"></DoubleAnimation>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Button.Triggers>
    </Button>

    <Button x:Name="Button4" Grid.Column="7" Content="Button 4">
        <Button.Triggers>
            <EventTrigger RoutedEvent="Button.MouseEnter">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation From="0.0" To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Button4" Duration="0:0:1"></DoubleAnimation>
                    </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Button.Triggers>
    </Button>
    </Grid>

Thanks in Advance

Tejus
  • 694
  • 1
  • 7
  • 19

2 Answers2

2

I don't think this is something you can do in XAML. In code it would look something like this:

XAML

<Button Width="50" Height="50" Name="MyButton"> </Button>

CODE

public partial class MainWindow : Window
    {
        private DispatcherTimer timer;
        private DoubleAnimation animation;
        private Storyboard sb;

        public MainWindow()
        {
            InitializeComponent();

            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += timer_Tick;

            MyButton.MouseEnter += (sender, e) =>
                {
                    timer.Start();
                };

            MyButton.MouseLeave += (sender, e) =>
                {
                    timer.Stop();
                };

            animation = new DoubleAnimation();
            animation.From = 1;
            animation.To = 0;
            animation.Duration = new Duration(TimeSpan.FromMilliseconds(1000));

            Storyboard.SetTarget(animation, MyButton);
            Storyboard.SetTargetProperty( animation, new PropertyPath(OpacityProperty));

            sb = new Storyboard();
            sb.Children.Add(animation);
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            timer.Stop();
            sb.Begin();
        }
    }
Core-One
  • 466
  • 2
  • 6
  • 19
2

Use BeginTime property and set it accordingly.

            <EventTrigger RoutedEvent="ButtonBase.MouseEnter">
                <BeginStoryboard x:Name="Sb">
                    <Storyboard>
                        <DoubleAnimation 
                               From="0" 
                               To="1" 
                               BeginTime="00:00:5"
                               Duration="00:00:5"                                   
                               Storyboard.TargetProperty="Opacity"/>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
            <EventTrigger RoutedEvent="ButtonBase.MouseLeave">
                <StopStoryboard BeginStoryboardName="Sb"/>
            </EventTrigger>
AnjumSKhan
  • 9,647
  • 1
  • 26
  • 38
  • Adding "BeginTime" only delays the start of the animation. The scenario explained in the question is, an animation should begin only if the mouse hovers or stays over an element for more than a second. Your solution only delays the animation, but will still complete the animation and will not provide the desired effect. @Core-One's solution worked out for me. – Tejus Jul 13 '16 at 22:45
  • @Tejus Both solutions do the same thing. Tell more clearly why my solution is not good. I test everything before posting. To test my solution, do this 1. keep your mouse for 5 seconds, and see the effect, 2. then, remove your mouse before 5 seconds to see no animation takes place. – AnjumSKhan Jul 14 '16 at 03:54