How to sublass TriggerAction?

Emon Haque 3,176 Reputation points
2021-05-05T14:15:58.87+00:00

I've this RepeatButton:

class ScrollButton : RepeatButton  
{  
    string icon;  
    public string Icon { get => icon; set { icon = value; setTemplate(); } }  
    void setTemplate() {  
        var border = new FrameworkElementFactory(typeof(Border));  
        var path = new FrameworkElementFactory(typeof(Path)) { Name = "thePath" };  
        path.SetValue(Path.StretchProperty, Stretch.Uniform);  
        path.SetValue(Path.FillProperty, Brushes.Gray);  
        path.SetValue(Path.DataProperty, Geometry.Parse(icon));  
        border.SetValue(Border.BackgroundProperty, Brushes.Transparent);  
        border.AppendChild(path);  
        Template = new ControlTemplate(typeof(RepeatButton)) {   
            VisualTree = border,  
            Triggers = {  
                new Trigger() {  
                    Property = IsMouseOverProperty,  
                    Value = true,  
                    Setters = {  
                        new Setter() {  
                            Property = Path.FillProperty,  
                            Value = Brushes.Blue,  
                            TargetName = "thePath"  
                        }  
                    },  
                    //EnterActions = { new Enter() },  
                    //ExitActions = { new Exit() },  
                }  
            }  
        };  
    }  
}  

and if I add it in my view this way:

var button = new ScrollButton() {  
    Width = 50,  
    Height = 50,  
    Icon = Icons.ScrollUp  
};  

the Trigger works:

93994-test.gif

I want to give it a ColorAnimation by subclassing TriggerAction class. I've tried this way:

public class Enter : TriggerAction { }  
public class Exit : TriggerAction { }  

but it gives me this error: 'TriggerAction' does not contain a constructor that takes 0 arguments. How do you subclass and add animations to it?

Developer technologies | Windows Presentation Foundation
0 comments No comments
{count} votes

Accepted answer
  1. DaisyTian-1203 11,646 Reputation points
    2021-05-06T07:00:54.867+00:00

    You can install Microsoft.Xaml.Behaviors.Wpf in NuGet and create Enter as below:

     public class Enter : TriggerAction<DependencyObject>  
        {  
            public Enter()  
            {  
            }  
      
            protected override void Invoke(object parameter)  
            {  
                
            }  
        }  
    

    But it may be impossible to use it like EnterActions = { new Enter() }. From the Microsoft Document TriggerBase.EnterActions Property, the EnterActions gets (no sets) a collection of TriggerAction objects to apply when the trigger object becomes active. This property does not apply to the EventTrigger class.
    And when I assign value to EnterActions like ExitActions = { new Exit() } , the error shows that Property or indexer 'TriggerBase.EnterActions' cannot be assgined to --- it is read only. It may be impossibe to implement with ExitActions =....

    You could add BeginStoryboard to EnterActions, I provide you a workaround as below:

    void setTemplate()  
            {  
                var border = new FrameworkElementFactory(typeof(Border));  
                var path = new FrameworkElementFactory(typeof(Path)) { Name = "thePath" };  
                path.SetValue(Path.StretchProperty, Stretch.Uniform);  
                path.SetValue(Path.FillProperty, Brushes.Gray);  
                path.SetValue(Path.DataProperty, Geometry.Parse(icon));  
                border.SetValue(Border.BackgroundProperty, Brushes.Transparent);  
                border.AppendChild(path);  
      
                Trigger trigger = new Trigger()  
                {  
                    Property = IsMouseOverProperty,  
                    Value = true,  
                    Setters = { new Setter() { Property = Path.FillProperty, Value = Brushes.Blue, TargetName = "thePath" } },  
                };  
      
                var enterAnimation = new ColorAnimation()  
                {  
                    From = Colors.Blue,  
                    To = Colors.LightPink,  
                    Duration = new TimeSpan(0,0,1),  
                    AutoReverse = true  
                };  
      
                var exitAnimation = new ColorAnimation()  
                {  
                    From = Colors.LightPink,  
                    To = Colors.Blue,  
                    Duration = new TimeSpan(0,0,1),  
                    AutoReverse=true  
                };  
      
                var propertyChain = new[]  
                {  
                   Shape.FillProperty,  
                   SolidColorBrush.ColorProperty  
                };  
                var propertyPath = new PropertyPath("(0).(1)", propertyChain);  
      
                Storyboard.SetTargetProperty(enterAnimation, propertyPath);  
                Storyboard.SetTargetProperty(exitAnimation, propertyPath);  
                Storyboard.SetTargetName(enterAnimation, "thePath");  
                Storyboard.SetTargetName(exitAnimation, "thePath");   
      
                var storyboard = new Storyboard();  
      
                storyboard.Children.Add(enterAnimation);  
                storyboard.Children.Add(exitAnimation);  
      
                var action = new BeginStoryboard();  
                action.Storyboard = storyboard;  
      
                trigger.EnterActions.Add(action);  
      
                Template = new ControlTemplate(typeof(RepeatButton))  
                {  
                    VisualTree = border,  
                    Triggers =  
                    {  
                        trigger  
                    }  
                };  
            }  
    

    The result like:
    94591-3.gif


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.