How to wait till ScrollViewer.ScrollToTop(); is finished? - c#

In my little application, I need to work with a TextBlock visual, but before I do that, I need to forcibly scroll to the top of the TextBlock content (TextBlock is enclosed in ScrollViewer]. So I call method
ScrollViewer1.ScrollToTop();
and program continues rendering TextBlock visual to a RenderTargetBitmap, but bitmap top part is not visible because of unfinished ScrollToTop(). If I scroll to top manually and then push button to proceed working with TextBlock visual, resulting bitmap is correct, but I want the program to continue automatically.
I could maybe implement a 1 or 2 seconds "pause" in background thread, but this is not how I would want to solve the issue. I need some notification, that the forced scrolling to the top was finished.
Any suggestions, please?
Thank you in advance.

A workaround would be listing to ScrollViewer.ScrollChanged Event
and checking ScrollViewer.VerticalOffset Property
when it is VerticalOffset appropriate range start execution of your code.

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.

C# WinForms label will display, but not show text

I'm designing a GUI and I have a label which I use effectively as a 'please wait' message after I invoke an action that tends to take a while. The label's text is static, I have set it in the properties in VS2010 for the label control.
When I hit that action on the form, I .Show() the control which is normally hidden until the time consuming process completes, then .Hide() it. When it hits the .Show() the label pops up (I know this because I have the BorderStyle set to Fixed3D so I see the border of the label show up) but there is no text in it whatsoever. I have tried setting the label to autosize and not to no avail, my text is set to black on gray, so no invisible ink, everything is visible, font is set. Code executes as I want it to throughout, theres just no text in the label. I'm at a loss.
Any ideas?
If the time consuming process is occurring on the same thread, then it could be a refresh/redraw issue (where the processor is too busy to handle UI requests). Try either refreshing the window before starting the long running process or, more appropriately, putting the time consuming process in a BackgroundWorker.
If the time-consuming process is not executing in a background thread, then your UI isn't updating because no message processing is taking place. Controls redraw themselves in WM_Paint messages.
Try calling Refresh on the control or on its window-handle parent (the form) after changing its state, before diving into the long process.
Or, move the long-running process into a background thread (see .NET 4.0 Task) to free up the UI thread.
Maybe I'm missing something, but why don't you just set label.Visible?

Scroll to a position in Scrollviewer with normal scrollanimation

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.

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