Sunday, February 11th, 2007
A year ago I wrote a small section about the Krypton Toolkit for inclusion in a planned book. Today I got my free copy.
It just goes to show how long it takes to put together a large book. My contribution talks about version 1.1 but we are now on version 2.4.1 with many more controls and palettes available than detailed in the book. Still, all publicity is good and this is even better because it is free.
The book is called Windows Developers Power Tools and has details about a whole heap of free software. It ranges from windows forms, asp.net, version control systems and much more besides.
Posted in General | No Comments »
Sunday, February 11th, 2007
After a week of hard work the Quick Access Toolbar is ready.
The ribbon control now has a collection property that you can use to define a list of button entries for the QAT. You can use the Visible and Enabled properties of the button entries to modify the display of them.
Here you can see the default location of the QAT, above the ribbon and with a couple of buttons defined. The mouse is over the customization button.

On pressing the customization button you get the following context menu allowing the user to alter the visible state of the individual entries.

If you add enough entries the ribbon will decide it cannot display them all. When this happens the customization button changes into the overflow button. Pressing the overflow button, as seen here, will display a popup with the extra items.

The customization button is then located at the end of the overflow popup.

You can alter the QAT to be shown below the ribbon.

The QAT is still shown when the ribbon is mimized, this mimics the behavior of the Office 2007 Ribbon.

Once I have implemented the ability to add content into the ribbon groups I will then come back allow the user to right click content to have them added to the QAT. This will then mimic the customization flexibility of the Office version.
Posted in Krypton Ribbon | No Comments »
Friday, February 2nd, 2007
Its a small start but you can use the QATShowBelowRibbon property to decide if the QAT is drawn above or below the ribbon.
At the moment all the QAT does is drawn a border and inside area, it does not have any actual content or customization button. Here you have the QAT above the ribbon in the caption area….

And now below the ribbon…

Posted in Krypton Ribbon | No Comments »
Friday, February 2nd, 2007
Usually I would wait until a new control was completed before investigating performance or memory usage. But the redraw of the ribbon was sluggish enough to warrant immediate action.
In my first programming job an experienced developer gave some great advice. Never try and predict where performance bottlenecks will occur and never try to optimize whilst developing. Always wait until you finish because you will always be surprised by the results. So trying to predict optimizations will often be wasted effort.
I’m not saying you should take this to the extreme; using a bubble sort on 1 million integers is obviously going to kill your application. But then again you should not compromise your clear design because you think it might have a performance problem. In reality the imagined problem might not occur and you have sullied the clarity of your design for no benefit.
Having said that, using the KryptonRibbon at debug time was showing slightly sluggish behavior and this was not going to change during the rest of the implementation. Actually it would only get worse as more display elements are added to the ribbon. So I fired up the excellent ANTS Profiler from red-gate software and had a look. The issue was pretty much where I expected it to be but it is good to have it confirmed.
Drawing the ribbon control requires a fair number of calculations and the use of many GDI+ objects. For example, drawing a individual ribbon group requires the use of several GraphicsPath, LinearGradientBrush and Brush drawing objects. So each time a ribbon group is drawn the drawing routine has to calculates sizes, creates the GDI+ objects, perform the actual drawing and then dispose of the GDI+ objects. All very neat and tidy but if the group is the same size, position and color on the next call to the drawing routine then a lot of wasted effort has gone into recalculating values and recreating GDI+ objects.
In order to cache calculation results and objects I used a variation on the well known memento design pattern. The drawing routine creates a memento instance that caches the calculated values and GDI+ object used during a drawing. This memento instance is returned as the result of the call back to the caller, in this case the ribbon group object. When the next paint occurs the memento is passed into the drawing routine. If the drawing routine determines the circumstances are the same it reuses the cached values, otherwise it will regenerate the memento contents. So all the drawing routines used by the ribbon objects take in a memento and return a memento.
But we need to be careful to avoid a leak. When the ribbon group is no longer needed it must ensure that any memento it is holding has its contents cleared down, to release any GDI+ objects it has. To achieve this a memento is always passed around as a reference to an IDisposable interface. This is perfect because outside of the drawing routine the memento is just a black box. Inside the drawing routine it will cast the interface to an actual concrete class. Once the ribbon group is destroyed it can call the IDisposable.Dispose method and know that its contents are safely cleaned up. So it achieves the twin aims of being a black box to hide implementation details outside the matching drawing routine but still allows it to be gracefully cleaned up.
Well it took a couple of days to update all the ribbon drawing routines to use memento objects and to test and ensure everything was working again. The end result was a 30% improvement in performance when performing a paint of the ribbon control. It now feels very smooth and seamless when resizing the owning form.
As with all performance work, you get a good gain from the first work you undertake because you are picking off the low hanging fruit. Once the control is completed I will look again to see if there are other areas where a useful percentage can be gained.
Posted in Krypton Ribbon | No Comments »