0

I have a canvas where i add more shapes programmatically. And for one of the shapes (a Path) i want to add a fill color that will flicker at every second (change from red to blue and back). I found an example on how to do that from xaml:

<Ellipse Fill="Red">
<Ellipse.Triggers>
    <EventTrigger RoutedEvent="Ellipse.Loaded">
        <EventTrigger.Actions>
            <BeginStoryboard>
                <Storyboard>
                    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
                                                  Duration="0:0:2"
                                                  FillBehavior="HoldEnd"
                                                  RepeatBehavior="Forever">
                        <ColorAnimationUsingKeyFrames.KeyFrames>
                            <DiscreteColorKeyFrame KeyTime="0:0:0" Value="Red"/>
                            <DiscreteColorKeyFrame KeyTime="0:0:1" Value="Blue"/>
                        </ColorAnimationUsingKeyFrames.KeyFrames>
                    </ColorAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger.Actions>                    
    </EventTrigger>
</Ellipse.Triggers>

But when i do it from the code i receive an ArgumentNullException: "{"Value cannot be null.\r\nParameter name: routedEvent"}"

This is my code:

 var sheetPath = new Path
        {
            Stroke = Brushes.Black,
            Fill = !isSelectedSheet ? Brushes.MediumSlateBlue : GetInvertedColor(Brushes.MediumSlateBlue),
            StrokeThickness = _lineWidth,
            HorizontalAlignment = HorizontalAlignment.Left,
            VerticalAlignment = VerticalAlignment.Center,
            Data = CreatePathGeometry(contour, height)
        };

        var colorAnimationUsingKeyFrames = new ColorAnimationUsingKeyFrames
        {
            Duration = new Duration(new TimeSpan(0, 0, 0, 300)),
            RepeatBehavior = RepeatBehavior.Forever,
            FillBehavior = FillBehavior.HoldEnd
        };

        colorAnimationUsingKeyFrames.KeyFrames.Add(new DiscreteColorKeyFrame
        {
            KeyTime = KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 100)),
            Value = Colors.Red
        });
        colorAnimationUsingKeyFrames.KeyFrames.Add(new DiscreteColorKeyFrame
        {
            KeyTime = KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 200)),
            Value = Colors.Blue
        });

        var storyboard = new Storyboard();
        storyboard.Children.Add(colorAnimationUsingKeyFrames);

        Storyboard.SetTargetProperty(storyboard.Children[0], new PropertyPath("(Path.Fill).(SolidColorBrush.Color)"));
        var beginStoryboard = new BeginStoryboard();

        beginStoryboard.Storyboard = storyboard;

        var eventTrigger = new EventTrigger();
        eventTrigger.Actions.Add(beginStoryboard);

        sheetPath.Triggers.Add(eventTrigger);

        canvas.Children.Add(sheetPath);
mm8
  • 163,881
  • 10
  • 57
  • 88
XamWaZZ
  • 59
  • 2
  • 12
  • *"a canvas where i add more shapes programmatically"* - don't do that. Use an ItemsControl instead, as shown e.g. here: https://stackoverflow.com/a/40190793/1136211 – Clemens Aug 29 '18 at 13:32
  • I can't do that. I have to create them dynamically. I have also text, some of the shapes are overlapping, i have to parse some objects in order to create them... – XamWaZZ Aug 29 '18 at 13:38
  • Anyway, do you have a suggestion for my problem? Or at least what's the problem in my code and why i get that exception? – XamWaZZ Aug 29 '18 at 13:38
  • All that doesn't mean you can't use an ItemsControl. You can still add text and have overlapping shapes, and you can of course also parse view model objects. Sooner or later MVVM turns out to be the superior approach. – Clemens Aug 29 '18 at 17:31
  • I had a problem with the dependency properties and that's the way i chose MPV pattern. – XamWaZZ Aug 30 '18 at 07:33

1 Answers1

1

Set the RoutedEvent property of the EventTrigger:

var eventTrigger = new EventTrigger();
eventTrigger.RoutedEvent = LoadedEvent;
eventTrigger.Actions.Add(beginStoryboard);
mm8
  • 163,881
  • 10
  • 57
  • 88
  • But since i create everything from the code, i am not in a view context, so i don't have a loadedEvent. Is there another way in order to start the eventTrigger? – XamWaZZ Aug 29 '18 at 13:49
  • 1
    @XamWaZZ: `LoadedEvent` is a static member of the `FrameworkElement` class; `eventTrigger.RoutedEvent = FrameworkElement.LoadedEvent;` – mm8 Aug 29 '18 at 13:52
  • Ah, great. Thanks. Now i have only a small problem. I want to change the color for an infinite number of times. "RepeatBehavior = RepeatBehavior.Forever". This line is not responsible for that? Cause right now i have only 1 flicker, from red to blue and that's all. – XamWaZZ Aug 29 '18 at 13:57