Unable to transfer animation from C# to C++, says property is in "read-only state"
Hello,
I have a custom control that will be used as a navigation bar with a select animation. I first created it in C# and it works fine as you can see on the youtube video.
This is the code that sets the animation into motion in C#:
And here it is in the C++
Whenever it tries to start the "moving" animation it says:
What is wrong or what should I do differently to get this animation running? It works fine in C# and it doesn't complain about the property being in read-only state.
I have a custom control that will be used as a navigation bar with a select animation. I first created it in C# and it works fine as you can see on the youtube video.
This is the code that sets the animation into motion in C#:
Code: Select all
double targetPosition = topOffset; // + point.Y;
IndicatorPositionAnimation.KeyFrames[0].Value = PreviousPosition;
IndicatorPositionAnimation.KeyFrames[0].KeyTime = KeyTime.FromTimeSpan(TimeSpan.Zero);
IndicatorPositionAnimation.KeyFrames[1].Value = targetPosition;
IndicatorPositionAnimation.KeyFrames[1].KeyTime = KeyTime.FromTimeSpan(new TimeSpan(0,0,0,0,200));
Transform trackRenderTransform = IndicatorTrack.RenderTransform;
if (trackRenderTransform is TranslateTransform translateTransform)
{
translateTransform.BeginAnimation(TranslateTransform.YProperty, IndicatorPositionAnimation);
}
IndicatorSizeAnimation.KeyFrames[0].Value = PreviousSize;
IndicatorSizeAnimation.KeyFrames[0].KeyTime = KeyTime.FromTimeSpan(TimeSpan.Zero);
IndicatorSizeAnimation.KeyFrames[1].Value = item.ActualHeight;
IndicatorSizeAnimation.KeyFrames[1].KeyTime = KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 200));
IndicatorTrack.BeginAnimation(HeightProperty, IndicatorSizeAnimation);
PreviousPosition = targetPosition;
PreviousSize = item.ActualHeight;
Code: Select all
const float targetPosition = topOffset;
IndicatorPositionAnimation->GetKeyFrames()->Get(0)->SetValue(PreviousPosition);
IndicatorPositionAnimation->GetKeyFrames()->Get(0)->SetKeyTime(KeyTime::FromTimeSpan(TimeSpan::Zero()));
IndicatorPositionAnimation->GetKeyFrames()->Get(1)->SetValue(targetPosition);
IndicatorPositionAnimation->GetKeyFrames()->Get(1)->SetKeyTime(KeyTime::FromTimeSpan(TimeSpan(0,0,0,0,200)));
Transform* trackRenderTransform = IndicatorTrack->GetRenderTransform();
TranslateTransform* translateTransform = DynamicCast<TranslateTransform*>(trackRenderTransform);
if (translateTransform != 0)
{
IndicatorPositionAnimation->Start(translateTransform, TranslateTransform::YProperty, GetTimeManager());
}
IndicatorSizeAnimation->GetKeyFrames()->Get(0)->SetValue(PreviousSize);
IndicatorSizeAnimation->GetKeyFrames()->Get(0)->SetKeyTime(KeyTime::FromTimeSpan(TimeSpan::Zero()));
IndicatorSizeAnimation->GetKeyFrames()->Get(1)->SetValue(item->GetActualHeight());
IndicatorSizeAnimation->GetKeyFrames()->Get(1)->SetKeyTime(KeyTime::FromTimeSpan(TimeSpan(0,0,0,0,200)));
IndicatorSizeAnimation->Start(IndicatorTrack, HeightProperty, GetTimeManager());
PreviousPosition = targetPosition;
PreviousSize = targetSize;
.LogNoesis: Warning: Cannot set 'y' property on object 'TranslateTransform' because it is in a read-only state
What is wrong or what should I do differently to get this animation running? It works fine in C# and it doesn't complain about the property being in read-only state.
-
-
sfernandez
Site Admin
- Posts: 3363
- Joined:
Re: Unable to transfer animation from C# to C++, says property is in "read-only state"
Hi, this error message means that a Frozen element (the TranslateTransform) is modified (by the animation). Could you please share the xaml where you define the TrackIndicator and the animation? Is this part of a template? I want to check what are we doing different from WPF.
In the meantime you can use a Storyboard to animate both properties by targeting the TrackIndicator, something like this:
In this case the storyboard is able to detect frozen elements in the animation property path, and clone them, so they can be animated.
In the meantime you can use a Storyboard to animate both properties by targeting the TrackIndicator, something like this:
Code: Select all
const float targetPosition = topOffset;
Storyboard::SetTarget(IndicatorPositionAnimation, IndicatorTrack);
Storyboard::SetTargetProperty(IndicatorPositionAnimation, MakePtr<PropertyPath>("RenderTransform.Y"));
IndicatorPositionAnimation->GetKeyFrames()->Get(0)->SetValue(PreviousPosition);
IndicatorPositionAnimation->GetKeyFrames()->Get(0)->SetKeyTime(KeyTime::FromTimeSpan(TimeSpan::Zero()));
IndicatorPositionAnimation->GetKeyFrames()->Get(1)->SetValue(targetPosition);
IndicatorPositionAnimation->GetKeyFrames()->Get(1)->SetKeyTime(KeyTime::FromTimeSpan(TimeSpan(0,0,0,0,200)));
Storyboard::SetTarget(IndicatorSizeAnimation, IndicatorTrack);
Storyboard::SetTargetProperty(IndicatorSizeAnimation, MakePtr<PropertyPath>("Height"));
IndicatorSizeAnimation->GetKeyFrames()->Get(0)->SetValue(PreviousSize);
IndicatorSizeAnimation->GetKeyFrames()->Get(0)->SetKeyTime(KeyTime::FromTimeSpan(TimeSpan::Zero()));
IndicatorSizeAnimation->GetKeyFrames()->Get(1)->SetValue(item->GetActualHeight());
IndicatorSizeAnimation->GetKeyFrames()->Get(1)->SetKeyTime(KeyTime::FromTimeSpan(TimeSpan(0,0,0,0,200)));
Ptr<Storyboard> storyboard = MakePtr<Storyboard>();
storyboard->GetChildren()->Add(IndicatorPositionAnimation);
storyboard->GetChildren()->Add(IndicatorSizeAnimation);
storyboard->Begin(IndicatorTrack);
PreviousPosition = targetPosition;
PreviousSize = targetSize;Who is online
Users browsing this forum: No registered users and 6 guests