What animation class would allow me to change the Visibility (not opacity) of a Grid object with a Storyboard instance in code (not XAML)?
So that I can set the to, from, and duration properties before adding it to the storyboard.
You can use an ObjectAnimationUsingKeyFrames with some DiscreteObjectKeyFrame.
You can find an example here. The only work to do is translating that to C# code. (Which shouldn't be a huge problem.)
This is the code necessary to animate the visibility.
DiscreteObjectKeyFrame dk;
ObjectAnimationUsingKeyFrames ok;
ok = new ObjectAnimationUsingKeyFrames();
dk = new DiscreteObjectKeyFrame();
Storyboard.SetTarget(ok, myGrid);
Storyboard.SetTargetProperty(ok, new PropertyPath(Grid.VisibilityProperty));
dk.KeyTime = TimeSpan.FromSeconds(0.1);
dk.Value = Visibility.Hidden;
ok.KeyFrames.Add(dk);
sb.Children.Add(ok);
Related
I'm using this solution for handling the long tap event: https://alexdunn.org/2017/12/27/xamarin-tip-xamarin-forms-long-press-effect/
It works fine when I use XAML, but I need to use code behind only. How can I add this command to the Image in the code behind?
Here is the code that creates my image:
var image = new Image
{
ClassId = item.Path,
Aspect = Aspect.AspectFill,
Source = item.ThumbNailImage,
Rotation = 90,
Margin = 10,
GestureRecognizers = { _tgr },
//Command here, but how?
};
This documentation on Microsoft's website is very helpful in explaining how to set attached properties in code.
So according to the example, your code should look something like this:
image.Effects.Add(new LongPressedEffect());
LongPressedEffect.SetCommand(image, myCommand);
Where myCommand is an ICommand.
This should create the LongPressedEffect, add it to the image, and then set the attached ICommand that determines the behavior.
Porting custom animation code from WP7 to store app. WP7 code successfully performed a page flip animation of a border object with a bunch of text boxes on it (that was a page to be flipped.) In the below code Storyboard.SetTargetProperty does not compile complaining that it wants a string:
DoubleAnimation anima = new DoubleAnimation
{
To = pageHostBaseIndex + 1,
Duration = CalculateFractionalDuration(pageHostBaseIndex + 1)
};
Storyboard storyboard = new Storyboard();
Storyboard.SetTarget(anima, this.PageTransition);
Storyboard.SetTargetProperty(anima, new PropertyPath(PageTransition.FractionalBaseIndexProperty));
storyboard.Children.Add(anima);
storyboard.Completed += Storyboard_Completed;
storyboard.Begin();
PageTransition derives from DependencyObject, it contains a DependencyProperty called FractionalBaseIndexProperty.
I tried putting in the string "PageTransition.FractionalBaseIndexProperty" as well as constructing a PropertyPath string. I also tried "(PageTransition).(FractionalBaseIndexProperty)" these all compile but fail with the exception:
No installed components were detected.
Cannot resolve TargetProperty PageTransition.FractionalBaseIndexProperty on specified object.
at Windows.UI.Xaml.Media.Animation.Storyboard.Begin()
I also tried EnableDependentAnimation = true, and making PageTransition derive from Timeline instead of DependencyObeject but these had no effect (same error.)
The eventual animation is a little complex but I don't think it's getting that far. Seems like a Silverlight to Universal difference in objects acceptable for binding to a storyboard or in something with the path. I'll bet there's a more XAML friendly way to do this now but at this point I'm trying to minimize the port and I'd like to keep the feel of the currently animation.
Thoughts?
After hours of tinkering and searching and then reverting some of my previous tinkerings I finally got past this. This thread got me thinking:
Windows 8 - Animating custom property in code-behind.
My border objects were already declared in XAML but my storyboard, animation and PageTransition objs weren’t.
So I added the following XAML in my UserControl.Resources:
<Storyboard x:Name="storyboard">
<DoubleAnimation x:Name="anima">
</DoubleAnimation>
</Storyboard>
<local:FlipTransition x:Key="Foo"></local:FlipTransition>
I used FlipTransition because in my case the PageTransition is an abstract class (so XAML wouldn’t let me instantiate it.) FlipTranstion derives from PageTransition.
Along with that I had to re-create new storyboards and animation objects (see below) with the same names as the ones in the above XAML (I don’t know why the ones I instantiated in XAML wouldn’t work.)
I also had to set EnableDependentAnimation = true
And last, the Path in SetTargetProperty had to change to PageTransition. FractionalBaseIndex (instead of the original PageTransition.FractionalBaseIndexProperty.)
DoubleAnimation anima = new DoubleAnimation
{
To = pageHostBaseIndex + 1,
Duration = CalculateFractionalDuration(pageHostBaseIndex + 1),
EnableDependentAnimation = true
};
Storyboard storyboard = new Storyboard();
Storyboard.SetTarget(anima, this.PageTransition);
Storyboard.SetTargetProperty(anima, "PageTransition.FractionalBaseIndex");
When all these came together it worked.
I implemented an infragistics Gauge (Radial and SegmentedDigitalGauge) into a custom user control, and now I am trying to add a Tooltip and it's not working. I create a new costum control with a new Gauge and worked. Someone knows what could be wrong?
This is the code
ToolTip tool = new ToolTip();
tool.AutoPopDelay = 5000;
tool.InitialDelay = 1000;
tool.ReshowDelay = 500;
tool.ShowAlways = true;
tool.SetToolTip(myGauge, "ToolTip Teste");
The gauge is inside a TableLayoutPanel, but I think it's not the problem..
EDIT
I discovered that the problem is not the ToolTip itself, but it happens when I add the gauge inside an ExpandableGroupBox. Otherwise it works properly. I still don't know how to fix it.
If the Radial gauge itself is a public property of the user control, you can set the tooltip text directly using the gauge control's ToolTipText property, otherwise you'll need to create a method to set said property.
Radial Gauge Documentation
For the Segmented gauge, it looks like you'll have to get the underlying gauge control from the GaugeComponent property, and then set the tooltip there.
Segmented Gauge Documentation
I have a storyboard that I would like to run multiple times. Unfortunately, after it runs the first time, even when this code is hit, it doesn't animate again. It only animates the first time. I'm setting an initial value....even when I set the value before I run it again.
DoubleAnimationUsingKeyFrames animateTransformX = new DoubleAnimationUsingKeyFrames();
EasingDoubleKeyFrame initialTransformXKeyframe = new EasingDoubleKeyFrame();
initialTransformXKeyframe.KeyTime = TimeSpan.FromSeconds(0);
//Resetting the value before running it again.
initialTransformXKeyframe.Value = 0;
animateTransformX.KeyFrames.Add(initialTransformXKeyframe);
EasingDoubleKeyFrame animateTransformXKeyframe = new EasingDoubleKeyFrame();
animateTransformXKeyframe.KeyTime = TimeSpan.FromSeconds(0.5);
animateTransformXKeyframe.Value = aDynamicValueGoesHere;
animateTransformX.KeyFrames.Add(animateTransformXKeyframe);
Storyboard.SetTarget(animateTransformX, image);
Storyboard.SetTargetProperty(animateTransformX, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)"));
Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(animateTransformX);
myStoryboard.Begin(this);
I feel like it is very simple but for the life of me I can't understand why. Any help would be appreciated.
EDIT
The reason I was doing it from codebehind is because storyboards are freezable and I have had trouble in the past with dynamic values in them. For simplicity I didn't put that I was using a dynamic value in the code; I updated the code above to show I'm using a dynamic value.
I tried adding the storyboard as XAML inside a resource with the use of a dynamic value. It works fine (and replays) if a non-dynamic value is used but it only plays once (the first time) when a dynamic value is used.
So, if {Binding OffsetX} were replaced with 50, for example, this works fine, and repeatedly.OffsetX gets updated through a property that implements INotifyPropertyChanged. Even if it were the same, if it were never updated, I would think it should still animate, just to the same value it animated to before (like it does with 50). But that isn't the case; it just doesn't animate again. So now I'm really lost.
<Storyboard x:Key="InitialAnimate">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)" Storyboard.TargetName="StoryImage">
<EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="{Binding OffsetX}"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
EDIT 2
I didn't fix the problem but I found a workaround that works for my particular situation. I was getting this error in my output window:
System.Windows.Media.Animation Warning: 6 : Unable to perform action because the specified Storyboard was never applied to this object for interactive control.; Action='Stop'; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='28715394'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='6255521'; TargetElement.Type='System.Windows.Controls.Grid'
I found a few StackOverflow answers regarding it, including how to find what Storyboard caused the issue and another unanswered question.
I am still not sure how to fix my original issue, but here's my workaround. Since I only needed the animation to run when you restarted (an event that happens in my viewmodel), I use an event raised in the viewmodel and consumed in the parent view to remove and then re-add the UserControl that contains the animation.
In that UserControl, I trigger the storyboard through a ControlStoryboardAction tied to a Loaded EventTrigger. This makes the animation run when it loads, and it only ever runs the animation once during the life of the UserControl. I am able to use the dynamic values in XAML. Here's how I'm removing and readding the view from it's parent:
Parent View:
<grid x:Name="imageHolder></grid>
Parent Codebehind:
private void CreateAnimations(object sender, EventArgs e)
{
imageHolder.Children.RemoveAt(0);
Views.Image image = new Image();
image.Name = "image";
imageHolder.Children.Add(image);
}
You can't change the Value property at runtime the way you're doing after the edit.
This is because Animations are freezable objects. There is more
information in the MSDN Documentation, but basically it means you
can't use binding because properties in the frozen object (i.e. the
animation) cannot change.
To get around this limitation, you will need to do some or all of the
work in code-behind.
See Why Storyboard value wouldn't get from a resource or binding?
So You probably want to go back to the codebehind method.
So as a final answer, what I would do is when I want to run it again:
Remove the previous storyboard
create a whole brand new Storyboard(or just the animation) and run that.
I am not sure what is going on here. I am following the example provided by Microsoft. Everything is done on the back end because I need to decide if you user should enter stuff into a text field or should the text field value be displayed as normal text. The code is as follows:
nameInput.Name = "inputName";
nameInput.Text = "Journey Name";
nameInput.KeyUp += onNameInput;
ColorAnimation animation = new ColorAnimation();
animation.From = Colors.Blue;
animation.To = Colors.White;
animation.Duration = new Duration(TimeSpan.FromMilliseconds(100));
animation.RepeatBehavior = RepeatBehavior.Forever;
Storyboard.SetTarget(animation, nameInput);
Storyboard.SetTargetProperty(animation, new PropertyPath(TextBlock.ForegroundProperty));
storyBoard.Children.Add(animation);
journeyStackPanel.Children.Add(nameInput);
ClockState state = storyBoard.GetCurrentState();
storyBoard.Begin(); //<---Crashes here
I am following the
http://msdn.microsoft.com/en-us/library/cc672995(v=vs.95).aspx
example. I am not sure what is going on, unfortunately the debugger does not spit out any more information. Maybe I am missing a step? I am sorry that I am being a little vague but this is all the information I have on the issue.
Any help is greatly appreciated!!
I was able to replicate this problem on the latest WP8 SDK, with the following error message generated:
ColorAnimation cannot be used to animate property Foreground due to
incompatible type.
I believe this is because you're trying to change the Foreground property of the TextBox to a Color object, but Foreground is actually a Brush object, hence the Type Mismatch error. Instead, you have to change the Color property of the Foreground object.
Try this instead:
Storyboard.SetTargetProperty(animation, new PropertyPath("(Foreground).(Color)"));