Automatic Smooth Resize Transitions - A Problem with Storyboards - c#

I have been trying for some time to create a class/series of classes that, upon detecting a resize in a related object, attempts to halt the resize of the object and create a smooth resize animation for it.
However, I have always had a problem with the objects 'flickering' on the screen for a second at the target size before the animation kicks in.
Long story short, after some serious debugging and self-doubt, I am under the impression that calling Storyboard.Begin() does not affect the target value until the next clock tick. I presume that this has something to do with Storyboard.Seek() not occuring until the next clock tick. (See the MSDN Reference). And as such, the object adopts its new height for a single frame before the animation kicks in which pulls it back to the starting height.
I have spent a long time trying to get this working because it's not nearly as simple as it seems. I can't set FrameworkElement.Height to the e.PreviousSize.Height in a FrameworkElement.SizeChanged event handler, because that affects the 'true' height of the object. As an example of why this doesn't work, is if something changes the 'true' height of the object while the animation is playing, then re-setting FrameworkElement.Height to the target height that was collected when the animation began could set it as an incorrect, out-dated value.
There's more things I've tried, and I'm sure they'll come up as answers arrive, but any ideas you have will be very much appreciated.

You'd probably have better luck by creating a layout container that handles the resize of the child objects, something like Robby Ingebretsen's Animated Panel.

Related

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.

How to create a visualization for a timer job

In my SL application I have a DispatchTimer which periodically refreshes data on the screen. I would like to create a visualisation for the user to show when the next refresh will happen.
My first thought was to change the timer (which currently runs every 20 seconds) to run every millisecond and, each tick, update a ProgressBar and count-down till the 20 seconds are up to run the main update method.
But I cannot shake the feeling that there's probably a better way of doing this. This feels quite heavy.
IS there a better way of doing this?
I would make an animated progress bar which resets on reaching the end.
Easiest would be to create two rectangles, one on top of antother with different colors.
Animate width of the one on the top from 0 to length of your progress bar.
You can control it by making a property which indicates how long should the animation last.
And maybe some start method to synchronize with refresh actions.
EDIT. There is example on msdn HERE (examples section)
The idea of a progres bar is not that bad. Updating every milisecond or each tick is much to often. 10 times a second would be enough.

Speeding Up Slow, CPU-Intensive Scrolling in WinForms

How can I speed up the scrolling of UserControls in a WinForms app.?
My main form has trouble scrolling quickly on slow machines--painting for each of the small scroll increments is CPU intensive.
My form has roughly fifty UserControls (with multiple fields) positioned one below the other.
I’ve tried intercepting OnScroll and UserPaint in order to eliminate some of the unnecessary re-paints for very small scroll events, but the underlying Paint gets called anyway.
How can I streamline scrolling on slower machines?
The tried-and-true method is to use an offscreen bitmap which is updated only when the data represented by your control actually changes; then, all OnPaint needs to do is render that bitmap to the screen.
If your paint process is intensive, and since you have so many controls, you'll find this makes a massive difference to the performance of your application.
Note that using the DoubleBuffering control property won't help in your case--it does tell WinForms to render to an offscreen bitmap before rendering to the screen, but that still happens at every paint cycle since WinForms doesn't keep track of when the representation has changed.
So, you'd have to roll your own. It's not that difficult. Here's what looks like a reasonably good article on the subject.
You can also increase the size of the scroll step. For example
panel1.VerticalScroll.SmallChange = 100;
Will cause the panel to scroll it's content 100 units vertically per click of the scrollbar button. So you take bigger steps each time, that might make the experience feel better at least. And you can do the same for the horizontal scroll bar of course.
I have used tabs to eliminate scrolling.

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).

Can I set an infinite AutoPopDelay for a tooltip in a .NET Windows Forms window?

I have a requirement to not have the standard .NET Windows Forms tooltip automatcially hide - that is, I need them to remain visible until the mouse moves off the control that has the tooltip. I'd like to avoid having to use specific MouseEnter and MouseLeave events for all controls with a tooltip. I'm happy to hear about third-party solutions if they'd solve the problem.
As it has been posted countless times and is known from the .NET Framework early days, you cannot set the AutoPopDelay time higher than an Int16.MaxValue (i.e. 32767) and have it working. Using the tooltip Show() method leads to the same result. Any value higher than 32767 leads the timer to be reset to 5000 ms.
Even an attempt to set the AutomaticDelay to a value that leads to an AutoPopDelay value higher than 32767 will cause the tooltip not to work. Furthermore, using the StopTimer() method doesn't yield any positive results.
The only way I was succesful in displaying a tooltip with infinite timeout was using the tooltip Show() method that passes the displayed position. tooltip.Show(text, control, position). In conclusion, the tooltip control has the most bizarre behavior I have yet encountered in a control and the documentation about setting the delay times is quite misleading.
I was searching for a solution to the problem
The popup baloon disappears too fast, not allowing me to read its content
The popup baloon does not appear again when hovering into that region.
I found in the forums the following answer, which does not solve Problem2, but lets me read the text for more than the time I need when I set its value to 32766 and is thus - in my opinion - a kind of 'work around':
Actually, I found out my problem was that I assigned a value higher than 32767 (32768 and higher will have an effect of 5 sec) really
weird, since AutoPopDelay is supposed to take an Integer (32 bit) as
parameter, and 32767 is really a signed 16 bit ...
But I have to admit, it still sucks...
But setting it to 32000 (32 seconds) seems to work better. No clue why this is but maybe it helps someone.
In my application, the tooltip text has to update every 10 seconds. What works for me is to deactivate and activate the tooltip every time this text is updated. When I set the AutoPopDelay to more than 10 seconds, the tooltip will effectively stay forever. So you might use a timer to repeatedly activate and deactivate the tooltip:
private void timer1_Tick(object sender, EventArgs e)
{
toolTip1.Active = false;
toolTip1.Active = true;
}
To minimize the flicker that happens on reactivating the tooltip, set the InitialDelay to 1. When you set the AutoPopDelay to 30000 and the timer interval also to 30000 you'll see a very short flicker only once every 30 seconds. For my application this short flicker is acceptable. Btw, don't forget to turn on the timer! (At first I thought it didn't work, until I discovered I forgot to turn on the timer ;-))
Of course this is a cure for the symptoms and not an elegant solution to the problem.
Try myToolTip.ReshowDelay = 0.
You just reshow the tooltip immediately after its delay expires. It worked for me.
This is not going to be the answer you want to hear... Roll your own. I once had scenario where I wanted to simulate the new Office's ribbonbar tooltip behavour for shortcut keyboard commands and I found that the standard tooltip API is just too limited.
Make a small, simple and border-less form instance for every control that you need a tooltip for. Then show and hide them non-modally as you do a mouse-enter or -leave event. Have the constructor for this window receive the UI control instance and let it query the control for it's events so that it can attach itself to the mouse-enter and -leave events, so that you wouldn't have to wire them up manually.
In my limited experience, I have found that setting the showAlways property to true has the side effect of making the tip display "infinitely" (until the cursor exits the control). This is not what the documentation says it will do, but that's what I have experienced. (However, I am using the Janus Supertip component, and it's possible that affects the behavior).
I think you are trying to cure the symptoms and not the cause of your problem.
You are trying to force a ToolTip to be something different from a ToolTip. A tooltip is, by definition, "a small "hover box" with information about the item being hovered over".
If the user can't read what the tooltip is trying to suggest in 30 seconds, then it isn't really a "tip" but an entire chapter from the help file. Put lengthy instructions into the Manual and do not attempt to force it into a ToolTip that stays open forever.
So, I ended up de-activating the tooltip, but I am still using it to hold the text for the tooltip, because it neatly adds itself to all the controls. I made my own panel and label inside it for the tooltip and dynamically positioned, made visible and populated the text on the mouse enter and mouse leave events of all the controls.
I also wrote a recursive function to add the mouse events to each label control (the only ones I have tooltips on), so I didn't have to manually to it and won't have to remember to do it when I add a new label. New developers on the project may not ever realise that the tooltip control is not actually rendering the tips.
Why a label in a panel? - so really big tooltips can scroll - although this is still not working nicely.
It is not real pretty, and I am still looking for a good answer if you've got on (or a critique of the method I've employed).
I came across http://www.binarymission.co.uk/, but their tooltip did not seem to render properly in my .NET 3.5 application. I am still talking to them.
The ToolTip.StopTimer method might help. From MSDN:
The ToolTip class has an internal timer that it uses to set the display duration for ToolTips. The duration associated with this timer is set through the AutoPopDelay property. The StopTimer method will stop this internal timer, causing any displayed ToolTip to be shown modally until the Hide method is called, or the parent form is minimized, hidden, or closed.
Set the ToolTipService.ShowDuration attached property to int.MaxValue:
<Button
Height="23" Width="75"
Content="Click Me"
ToolTip="My ToolTip" ToolTipService.ShowDuration="2147483647"
/>

Categories

Resources