简体   繁体   中英

Animations and Routed Event Handlers

So I am trying to create a basic animation that is triggered when a alarm clock goes off. The animation would be an opacity animation that lowers the opacity of the entire UI or parts of it to 0 or 50 (depending on the part).

Now after trying many tutorials on lowering a opacity of a object it hit that all these animation tutorials run off a "Button.Click" or "Button.IsEnabled" event. I need mine to be launched with out a Button of any kind or some other user interface click.

I did find this, it shows the ability to make a RoutedEvent MSDN Create Custom RoutedEvent

The Code I need to add it to is as follows:

        private void timer_Tick(object sender, EventArgs e)
    {
        TimeTop.Content = DateTime.Now.ToString("h" + ":" + "mm" + " " + "tt");
    }

    private void dispatcherTimer1_Tick(object sender, EventArgs e)
    {
        label1.Content = DateTime.Now.ToString("hh") + ":" + DateTime.Now.ToString("mm") + " " + DateTime.Now.ToString("t"+2);
    }

    private void dispatcherTimer2_Tick(object sender, EventArgs e)
    {
        //Alarm settings
        if (label1.Content.Equals(label2.Content))
        {   
            //Actual Wake Up Call
            //TOOK OUT WAKE UP CALL
            TimeOfDayCB.Text = "";
            HourAlarmCB.Text = "";
            MinuteAlarmCB.Text = "";
            label2.Content = "";
        }
    }

So how would I go about adding it? Also was the source I gave useful and could help me do this task?

The best way to do what you want is to use a DataTrigger, bound to some property in your code. This kind of animation is easiest to initiate from code.

Here is a style that starts animation when the bound property changes:

<Style x:Key="timerTriggeredFlash" TargetType="Label">
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Window},
                    Path=DataContext.StartFlashing}" Value="True">
            <DataTrigger.EnterActions>
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" 
                                            From="0" To="1" RepeatBehavior="3x" />
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.EnterActions>
        </DataTrigger>
    </Style.Triggers>
</Style>

Note that my ViewModel has a public boolean property, StartFlashing , when I set it to true, any label that uses that style has its Opacity animated on and off, three times.

To use the style, refer to the style name when you declare your label, like this:

<Label Grid.Row="1" 
       Background="Red" 
       Style="{StaticResource timerTriggeredFlash}" 
       Content="Flashing label" />

My ViewModel looks like this:

public class MainWindowViewModel : INotifyPropertyChanged {
    DispatcherTimer _Timer;

    public event PropertyChangedEventHandler PropertyChanged;

    public MainWindowViewModel() {
        _Timer = new DispatcherTimer();
        _Timer.Interval = TimeSpan.FromSeconds(1);
        _Timer.Tick += new EventHandler(_Timer_Tick);
        _SecondsLeft = 3;
        _Timer.Start();
    }

    void _Timer_Tick(object sender, EventArgs e) {
        SecondsLeft = SecondsLeft - 1;
        if (_SecondsLeft <= 0) {
            StartFlashing = true;
            _Timer.Stop();
        }
    }

    private int _SecondsLeft;
    public int SecondsLeft {
        get { return _SecondsLeft; }
        set { 
            _SecondsLeft = value;
            if (PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs("SecondsLeft"));
            }
        }
    }

    private bool _StartFlashing;
    public bool StartFlashing {
        get { return _StartFlashing; }
        set { 
            _StartFlashing = value;
            if (PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs("StartFlashing"));
            }
        }
    }
}

Finally, my main form's code-behind connects to my ViewModel like this:

public partial class MainWindow : Window {
    public MainWindow() {
        InitializeComponent();
        this.DataContext = new MainWindowViewModel();
    }
}

The key aspect here is that

  1. DataTriggers allow you to initiate an animation from code
  2. Your DataTrigger should be bound to a property in your DataContext, in this case a ViewModel
  3. In case you haven't worked with ViewModels before, you can bind their public properties if you implement INotifyPropertyChanged or create your properties as DependencyProperties

Basically I found out a way to make a animation happen in the C# coding itself, without event triggers or XAML, or a storyboard. To recreate what did this is all you need: MSDN Animation Without Storyboard

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM