0

I have a problem which is certainly very trivial, but i am a beginner in coding C# and i simply can't understand why the code fails.

I want to animate shapes and have the option to pass in the property as a parameter. I.o.w.: i want to specify an animation property (path) using a variable.

This leads me to try the following:

public static class HelperExtension
{
    public static void Animate(this UIElement target, string propertyToAnimate, double? from, double to, int duration = 3000, int startTime = 0)
    {
        var doubleAni = new DoubleAnimation
        {
            To = to,
            From = from,
            Duration = TimeSpan.FromMilliseconds(duration)
        };

        Storyboard.SetTarget(doubleAni, target);
        PropertyPath myPropertyPath; 

        // option 1: fails:
        string _mypropertypathvariablestring = "Rectangle.Width";
        myPropertyPath = new PropertyPath(_mypropertypathvariablestring); 

        // option 2: succeeds:
        myPropertyPath = new PropertyPath("(Rectangle.Width)");         

        Storyboard.SetTargetProperty(doubleAni, myPropertyPath);


        var sb = new Storyboard
        {
            BeginTime = TimeSpan.FromMilliseconds(startTime)
        };

        sb.Children.Add(doubleAni);
        sb.Begin();
    }
}

The compilation succeeds, but execution throws exception with the message:

System.InvalidOperationException: Cannot resolve all property references in the property path '"Rectangle.Width"'

at

sb.Begin();

I don't understand how option 1 and 2 differ (which are meant to be implemented not at the same time).

Could someone help by telling me what i misunderstand? Most likely s.th. on the conceptual level

And maybe providing a hint how to best use variables in new PropertyPath()?

Joel Bourbonnais
  • 2,618
  • 3
  • 27
  • 44
frhiso
  • 11
  • 3
  • Possible duplicate of [Creating Storyboard in code behind in WPF](https://stackoverflow.com/questions/15900627/creating-storyboard-in-code-behind-in-wpf) – Joel Bourbonnais Mar 14 '18 at 19:44
  • Hello KOTIX, thank you for your quick reaction. To my understanding the differentiator is the aspect of using a variable in the PropertyPath, which is what i am predominantly interested in. Implementing a storyboard based animation from code behind in general is not an issue for me, that is well discussed in other posts indeed. I just add this to make my emphasis on the variable aspect more clear. – frhiso Mar 14 '18 at 20:16
  • 1
    The parentheses matter. It's all explained in [PropertyPath XAML Syntax](https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/propertypath-xaml-syntax), section [PropertyPath for Animation Targets](https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/propertypath-xaml-syntax#propertypath-for-animation-targets). The version without parentheses assumes that there is a Rectangle property holding an object with a Width property, which you don't have. You could simply write `new PropertyPath("Width")` – Clemens Mar 14 '18 at 20:26
  • 1
    Even simpler: `target.BeginAnimation(UIElement.WidthProperty, doubleAni)`. Note that you don't need a Storyboard at all. – Clemens Mar 14 '18 at 20:32

1 Answers1

1

@ Clemens: perfect, that solves my problem and is the answer from my perspective.

I looked for options to mark a comment as answer, but obviously there is a reason (Mark a comment as answer to a question) not to have it. If the moderator would have options to mark Clemens comment as answer and agrees, i'd feel this would be the right way to have it.

For the time being a recapitulation of what i believe to have learned from Clemens' comment:

Syntax that works:

myPropertyPath = new PropertyPath("(Rectangle.Width)");
string _mypropertypathvariablestring = "(Rectangle.Width)"; 
string _mypropertypathvariablestring = "Width";

Syntax that fails:

myPropertyPath = new PropertyPath("Rectangle.Width");
string _mypropertypathvariablestring = "Rectangle.Width";

I.o.w.: whenever the type is to be specified in a PropertyPath, it demands to use parentheses in order to indicate a "partial qualification" and that type to be within the default XML namespace, as a shape like Rectangle does. In all other cases just the property itself is sufficient.

Since i attempt to implement a pure CodeBehind solution, i didn't consider "PropertyPath XAML Syntax", and sticked with "PropertyPath Class", which is more concise and does not involve the "paranthesis" syntax.

But my initial fault was the misconception, that the PropertyPath would have to include the object the property(chain) gets attached to, fueled by the working syntax option

myPropertyPath = new PropertyPath("(Rectangle.Width)");

which i found by trial and error, without the understanding of the meaning of parentheses.

Thank you also for pointing out the option to implement the animation without using a storyboard and proposing the better implementation option via BeginAnimation.

Thanks again!

frhiso
  • 11
  • 3