Scroll to a position in Scrollviewer with normal scrollanimation - c#

I have a metro styled app with a scrollviewer. Now I would like to scroll to a position when the user clicks a button. I tried:
MainScrollViewer.ScrollToHorizontalOffset(x);
But then its "jumping" there quickly. I want to have a smooth animation up to x.

There is no API out of the box that would allow you to do that.
There is also no property that you could target with an animation.
You would need to either use frame-based animation (basically figure out where you are in the timeline and on each CompositionTarget.Rendering event - update the offset) or create an attached dependency property that calls ScrollToHorizontalOffset when its value changes and target that property with an animation.

You could create a method that runs async and has a timer which increments the ScrollToHorizontalOffset(int x).
Say every 500ms it adds 10px.

Related

Is changing the margin of a rectangle a bad method for animation?

I am trying to create a video track bar in C# using WPF with the goal of emulating a standard track bar such as Youtube's which allows the user to drag the thumb to a new position updating the video's position in real time as it is moved.
Currently I have a dispatcher timer on the video player which detects when the video's current frame has changed at which point it calculates the thumb's (Left) margin (# of frames * pixelsPerFrame).
When the user's mouse is pressed on the slider it then pauses the video, starts to track the mouse's X position and maps that to a frame and sets the videos current position.
It is kind of working however the motion is rather jumpy (The playback is fine, its the slider moving that is strange) and towards the end of the slider the rectangle (thumb) is kind of distorted. It gets thinner and some times actually disappears.
Is animating the slider through the margin inefficient and is there a better way to achieve this kind of (interactive?) animation?
Yes, animating the thumb via the Margin property is quite inefficient because it requires WPF to recalculate the layout of the control and re-render it every time there is an update.
The more efficient method of animating visuals in WPF the way you want to is to use a TranslateTransform attached to the item's RenderTransform property. Changing the X and Y properties of the TranslateTransform will immediately alter the item's screen location without the expensive layout recalculation. Best of all those properties are DependencyProperty's so they can be data bound to properties in your view.

SurfaceListBox not responding to touch gestures for several seconds

I have a WPF-program that has a grid with two columns. First one has buttons and second one has WindowsFormsHost-element that embeds an ActiveX component. One button hides the WindowsFormsHost-element and shows a SurfaceListBox on the same location on screen in the second column. If I have touched the WindowsFormsHost element just before pressing this button, it takes approximately 8 seconds from the last touch until the SurfaceListBox becomes responsible for touch gestures.
The thread is probably not blocked, because I can use the buttons in another column, and use use the ListBox with mouse.
The ListBox remains unresponsive for touch events forever, if I touch it within the 8 second waiting time. So it seems that somehow the ListBox does not get the touch events.
If I programmatically create another ListBox, it does not work either, for 8 seconds, if it is placed in same are on screen than the WindowsFormsHost was.
I noticed there is a method CaptureTouch() for UIElement, but I cannot get hold of to the TouchDevice that I could pass it as parameter. I have set ManipulationEnabled="true" for every UIElement and no TouchEvent will be fired.
I have also desperately used UpdateLayout() etc with no luck.
So I think the touch gestures are somehow routed wrong and after the waiting time it implicitly fixes the routing, but is there a way I could make the touch gestures work in the ListBox immediately?
The problem disappeared when I removed "focus tracking for launching on-screen keyboard" from my program.
So in case of somebody else struggles with the same problem,
http://www.infragistics.com/community/blogs/blagunas/archive/2013/12/17/showing-the-windows-8-touch-keyboard-in-wpf.aspx and SurfaceListBoxes aren't meant for each other.

Windows store app, horizontal scrolling when too much text

I am making an app for the Windows store (xaml/c#), in this app i create a list of properties of a file. One properties is the file path, this is always too long. my solution would be to make this side scrolling when this textblock is selected.
the text would start to scroll when selected to make all the information readable. (ticker bar)
I can’t find a property to achieve this, and I find it difficult to make a custom function for this. Can you help me?
I'd reconsider the idea. I had the idea many times and it was always rejected by designers. I think animating text is likely to be more annoying than clipped text. A better way might be to either wrap it in place or if you are in a list with limited item height - only show the full text after it was tapped - either with some popup or in the details view of the tapped item.
Having said that - to animate it you'd put the TextBlock inside of a Canvas, set the Clip of the Canvas to a RectangleGeometry that defines your clipping region (and update it on size updates), then animate the Canvas.X property of the TextBlock. The problem with that is that Canvas.X is not an "independent" property and so you'd need to set DoubleAnimation.EnableDependentAnimation="true" on the animation and could still get a fairly choppy animation.
A better choice might seem to be to animate the RenderTransform of the TextBlock (e.g. set it to a TranslateTransform and target the X property of the transform in the animation), but last time I checked - this could animate the TextBlock in an already clipped form, so you still wouldn't see the part of it that doesn't fit on screen. You could try that though.
Putting the TextBlock in a ScrollViewer might work better, but it would suffer from similar problem as the Canvas solution since the ScrollViewer doesn't even have an animatable offset property. In Windows 8.1 you get built in animations when you call ScrollViewer.ChangeView(), but that would likely animate too quickly. It is possible with the help of a proxy dependency property or other per-frame dependent animation as in the ScrollToHorizontalOffsetWithAnimation() ScrollViewer extension method in WinRT XAML Toolkit.

Issue with how to slide user control left/right

I have a view and within the view, there are two user control, each with a button on it. When the page loads, the first user control will load. when i click on the button in the first user control, I would like to slide the first user control left, making it invisible and display the second user control. when i click on the button in the second user control, I would like to slide the second user control right, making it invisible and displaying the first user control again. can anyone help on how to achieve this?
If I get correctly, you want something like Carousel in wpf. In case that's it, here's the link. It allows you to slide several items left-right to switch between them.
Another way to go would be using default animations in WPF, meaning DoubleAnimation applied to Margin property that increases margin from 0 to 500 (to move it off the screen) and back to 0 (to return it) or something like that. Head's up for double animation and moving controls is here and official documentation here.
Rather than hard-code an animation designed for your specific scenario, you could do something a little more generic and adapt the TransitionControl that uses pixel shaders. Set the content property and you can specify which shader effect you want it to apply as the transition.

Animate a e.Graphics.DrawLine with arrowhead

I need to "animate" an arrow. It can go in any direction (up, down, left, right and diagonals) and the arrowhead will be at the end. It needs to appear as if it is growing from orgin to the end.
To make matters more complicated it has to be in a user control so it is possible to add to the controls collection in the forms and remove it to delete it from the screen, and its background is really transparent (no color.transparent) so i can't paint the background to "clear" the previous line.
I have it static already (drawn from origin to end) but i can't animate it. I tried to add a timer in the user control but I fail to get a correct algorithm to calculate the intermediate ends of the line while it is growing.
Any help would be appreciated.
Thanks
When using animation on a Windows form you have to use another thread. Look into using a background worker: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
You don't need another thread - I have succesfully implemented Windows Forms animation.
My design:
Use a Windows.System.Forms.Timer object to call a callback function 'Animate()' at regular intervals
the Animate() function updates a property of your arrow, and then calls Invalidate() on the windows control
this all happens in the same UI thread, so yuo will not get any flicker effects (as long as your control has double duffering switched on).

Categories

Resources