Smiling Smith
Software development fragments and thoughts
Friday, August 26, 2016
Monday, July 13, 2015
WPF ProgressBar IsIndeterminate behavior
Today I found that hiding (collapsing) a WPF ProgressBar control with IsIndeterminate set to true does not stop the control from using the CPU. I am using this control in the status bar of a WPF application as a visual hint to the user that some background task is progressing, a sign that the application is busy.
My approach was simply to show or hide the control with the IsIdeterminate property preset to True in XAML, by binding to the Visibility property. This proved painfully wrong while testing on a colleague's notoriously slow PC - while idling the application was using CPU (way too much).
Interestingly, when you first create the control in collapsed state, the animation is not enabled, only when it is displayed. After that, the animation code seems to be running all the time. My solution was to bind the same boolean property used to show or hide the control to the IsIndeterminate property. This way I managed to get the CPU down to zero while idling, the way I thought it should be.
The funny part is that this control was also being used on a grid to display the loading status of the underlying list of elements. Ouch...
My approach was simply to show or hide the control with the IsIdeterminate property preset to True in XAML, by binding to the Visibility property. This proved painfully wrong while testing on a colleague's notoriously slow PC - while idling the application was using CPU (way too much).
Interestingly, when you first create the control in collapsed state, the animation is not enabled, only when it is displayed. After that, the animation code seems to be running all the time. My solution was to bind the same boolean property used to show or hide the control to the IsIndeterminate property. This way I managed to get the CPU down to zero while idling, the way I thought it should be.
The funny part is that this control was also being used on a grid to display the loading status of the underlying list of elements. Ouch...
Wednesday, October 23, 2013
Layout Cycle Detected - My story
If you are reading this then probably you hit one of the Silverlight errors I dread the most. Sometimes you see an error message, other times your screen just goes blank. Once I managed to intercept an exception in Visual Studio's debugger, but that was a very lucky shot.
There are a few links on the web that explain what is going on, and I followed this one on StackOverflow which proved to help me a lot. In my case I have a relatively complex Gantt chart -like user control that allows for zooming and scrolling. Individual Gantt items are also relatively complex user controls that need to be re-sized when the parent control is itself re-sized or when the user zooms in or out.
My initial implementation approach, which proved to be reliable on early tests, was to use the Gantt item child user control's SizeChanged event to re-size and re-position internal elements. As I said, this proved to work reliably with a limited number of items. When I started to test the main control with real live data, the problem emerged.
The fault was on the design itself - you should never change the size of your user control inside the user control's SizeChanged event. Never. This will trigger a recursion loop that the layout engine may never recover from and you will get the dreaded exception, or blank screen.
My solution was very simple - I moved all of the code from the event handler to a public method that is called from the parent control's code. This works well because there is no other instance that re-sizes the child control but its parent, so there is only one entry point for calling the code. Instead of assigning a value to the children's Width property, now the parent user control code calls a SetWidth method on the child that besides setting the width, also executes the re-sizing logic outside the SizeChanged event handler. Voilá.
There are a few links on the web that explain what is going on, and I followed this one on StackOverflow which proved to help me a lot. In my case I have a relatively complex Gantt chart -like user control that allows for zooming and scrolling. Individual Gantt items are also relatively complex user controls that need to be re-sized when the parent control is itself re-sized or when the user zooms in or out.
My initial implementation approach, which proved to be reliable on early tests, was to use the Gantt item child user control's SizeChanged event to re-size and re-position internal elements. As I said, this proved to work reliably with a limited number of items. When I started to test the main control with real live data, the problem emerged.
The fault was on the design itself - you should never change the size of your user control inside the user control's SizeChanged event. Never. This will trigger a recursion loop that the layout engine may never recover from and you will get the dreaded exception, or blank screen.
My solution was very simple - I moved all of the code from the event handler to a public method that is called from the parent control's code. This works well because there is no other instance that re-sizes the child control but its parent, so there is only one entry point for calling the code. Instead of assigning a value to the children's Width property, now the parent user control code calls a SetWidth method on the child that besides setting the width, also executes the re-sizing logic outside the SizeChanged event handler. Voilá.
Tuesday, January 10, 2012
Silverlight, Library Caching and blank screens
Here's the scenario: You have a Silverlight 4 application with a splash screen. You business is growing and so is your Silverlight application's xap size. What can you do about it? Wouldn't it be nice if you could somehow split the xap into smaller and reusable files? This is exactly what the "Library Caching" feature is supposed to do: your reusable libraries are packaged into zip files and stored in your browser's cache, reducing the initial download bandwidth.
Theoretically all works well, of course. Until your customers start complaining about blank screens after the xap is downloaded on IE9. To get the application to start, they have to press F5 once (sometimes more). A brief internet search shows that this is a known and reported issue, but as you can see it's solved because Microsoft cannot reproduce it.
So now I have to go back and recompile the xap as a monolith to avoid this nice little feature that only "works" on IE9. How dumb is this?
Theoretically all works well, of course. Until your customers start complaining about blank screens after the xap is downloaded on IE9. To get the application to start, they have to press F5 once (sometimes more). A brief internet search shows that this is a known and reported issue, but as you can see it's solved because Microsoft cannot reproduce it.
So now I have to go back and recompile the xap as a monolith to avoid this nice little feature that only "works" on IE9. How dumb is this?
Saturday, February 12, 2011
The skewed accelerometer
What can you do if your WP7 accelerometer is not correctly calibrated? As I found out, there seems to be no OS mechanism to calibrate the accelerometer. So if you have a production device you will have to return it for repair or replacement. But what do you do if you have a loaner preproduction device like I do? Well, you have to fix the accelerometer the only way you can: through software.
A correctly calibrated accelerometer should return the vector (0, 0, -1) when you place your device with the screen up on a flat surface (like your office floor). If you have a skewed accelerometer like I do, then you should be able to compensate the difference to the reference vector, once you know what your device is reporting when placed on the floor with the screen up.
To do just that, I wrote a very simple Silverlight application for WP7 that polls the accelerometer every second and displays the vector components, both the sampled value and an average value in order to smooth out the natural variations in the sampling.
You can get the sample application with source code here. After running this app on the floor, I noticed that the Y component of the accelerometer vector was slightly skewed to -0.15, while all other components reported the expected values. After adding 0.15 to the Y component, I got back a calibrated accelerometer.
Now I can get back to my XNA gravity ball code and make it work like it should.
A correctly calibrated accelerometer should return the vector (0, 0, -1) when you place your device with the screen up on a flat surface (like your office floor). If you have a skewed accelerometer like I do, then you should be able to compensate the difference to the reference vector, once you know what your device is reporting when placed on the floor with the screen up.
To do just that, I wrote a very simple Silverlight application for WP7 that polls the accelerometer every second and displays the vector components, both the sampled value and an average value in order to smooth out the natural variations in the sampling.
You can get the sample application with source code here. After running this app on the floor, I noticed that the Y component of the accelerometer vector was slightly skewed to -0.15, while all other components reported the expected values. After adding 0.15 to the Y component, I got back a calibrated accelerometer.
Now I can get back to my XNA gravity ball code and make it work like it should.
Subscribe to:
Posts (Atom)