UI frozen when updating pie-chart control - c#

I'm using the chart controls from WinRTXAMLToolkit, to draw a pie chart. The chart is updated on the screen using the values from a few slider controls.
When the sliders values are changed, I call in a function to calculate a formula (say compound interest) based on the sliders' values.
And then I change the ItemsSource of the chart's SeriesDefinitions to point to the new collection of data.
I'm trying to have a 'live' PieChart which updates instantly. The problem is when I keep changing the values of the sliders, there is a 1-2 second delay for the chart to draw itself again - and this makes the slider movement 'freeze' in between for a second.
Is there any way around this problem ? Can I move the chart-updation to a different thread so that the UI thread remains free and doesn't freeze up ?

Try update it using another thread and run it async.
One way is to insert it into Update fuction, and do:
await Update()
While Update and the method which it called in are async.

I think that the problem may be that you're changing the ItemsSource. This is a more intensive operation because a lot of things happen in the background. Could you use an ObservableCollection and update it instead of replacing it?

Related

Rendering same text for multiple TextBlocks in WPF

So I have a ListView with a UniformGrid of 16 rows and 32 columns as it's ItemsPanelTemplate. ItemsSource is bound to an ObservableCollection of objects that have two properties: IsSelected and Value. Each cell in the UniformGrid contains a TextBlock whose Text property is bound to the Value Property of its respective item. Below this construct, I have a ScrollBar whose value ranges from 0 to 255. Adjusting this ScrollBar changes the Value Property of the selected items in this grid.
Now that I've painted that picture, here is the problem. The issue is when I have many slots selected, and change the value of the ScrollBar, it updates all of the TextBlocks at once, causing visible lag. I scoured the internet for a solution to this problem, reading many articles on improving rendering performance and such. I have tried using Glyphs to try and increase the speed of text rendering, which showed improvement, but the lag was still painfully visible.
If I can somehow render the text only once per value change, and copy it to all other selected slots, I think this would improve performance. Is there a way to do this? If not, is there a different way I should be doing this kind of thing?
If not all of them are visible you could look at reducing your lag by looking into using VirtualizingStackPanel property.
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
http://miteshsureja.blogspot.com/2011/05/virtualizing-stack-panel-in-wpf.html
Additionally, if it's because of the speed at which a scrollbar can change value, and the draw of the UI just can't keep up....you could use a Timer that gets restarted anytime the scrollbar/slider changed event is called.
Once the timer elapses (lets say you pick 1 second) without being restarted by the change event, then it updates the value that the boxes are all binded to so that it only updates once the user stops moving the scrollbar/slider.
There does not seem to be a a way to easily copy the rendered text to other TextBlocks. The only way to increase render performance whilst maintaining immediate response was to switch to Glyphs. Will update answer if I find a way to render text once, and copy it to the remaining Glyphs.

Simple multi-threading issue

I have a class called Movement which moves a picture box (guy on the left) on my form to a random position when it's Lead method gets executed. I also have a method which moves another picture box (dark guy on the right) called SetMrShadowToMove. These two picture boxes are suppose to move at the same time and arrive at the random point (one point for both picture boxes) at the same time.
For now, these methods use a timer to move the picture boxes, but my main intention was to have a loop which runs until the picture box's coordinates meet the random point picked while using Thread.Sleep to delay the process and make an animation of it.
To do that, I need to run both methods on different threads, so my UI thread doesn't get frozen and these methods would run at the same time.
My problem is that I don't know how to run these methods on different threads, and also don't know how to access the picture boxes on the other threads (it seems that this has something to do with invoking and stuff!).
What is the best way to solve this problem?
The best way (in my opinion) is by using a background worker.
those things can do there calculations in the background. If you you want to update the interface after that you can use there report progress event to invoke your main (interface) thread and redraw the screen. You can also the work complete even if you want to have a event of the background worker as a final even (for example if mister shadow is 'destroyed' or something).
I don't know your code of mister shadow so I don't have any direct example code for you. But a full example about how to use a background worker can be found on msdn here. I hope this will help you.

Visual studio c# pie chart will not redraw

I am using winforms and attempting to create a pie chart which will update on a button click. I have added two points to the charts series via the designer. I am sure the values of the points are being changed however the chart itself is not updating to show this.
chart1.Series["Series1"].Points[0].SetValueY(results["TimeFrame1"].Count);
chart1.Series["Series1"].Points[1].SetValueY(results["TimeFrame2"].Count);
This updates the two points. I have tried calling chart1.update() however it did not redraw the chart. Is there some method I am not aware of to make the chart redraw. Thanks
Instead of manually setting your points inside your series, why not use databinding? That way whenever the underlying data source changes, your chart will change too. Here is another SO answer with some additional info:
How to bind data to chart in winforms and refresh chart?
Alternatively, try calling chart1.Refresh() instead of chart1.Update().

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.

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