SilverlightSerializer 2.0 and protobuf-net offer substantial improvements on the default binary serialization done by WCF. They can be used to create byte arrays for the objects being serialized in a service consumed by Silverlight. Protobuf-net is a .NET implementation of protocol buffers. protocol buffers is name of the binary serialization format used by Google, and is known to be very fast and efficient. Protobuf-net is compatible with most of the .NET family of frameworks. SilverlightSerializer is a less well-known binary serializer which was developed specifically for Silverlight. It is particularly simple to use.
I adapted a project using SilverlightSerializer to use protobuf-net. Protobuf-net offered improved reduction in the size of WCF messages, but I observed that there seemed to be a smaller difference in the message sizes with larger objects than with small ones. I decided to test how the two compared in serializing (relatively) large objects.
I also investigated the benefits of using QuickLZSharp compression on Protobuf-net serialized byte arrays. Compressing SilverlightSerializer byte arrays with QuickLZ has already been shown to be highly beneficial. For protobuf-net serialized arrays, it offered a small benefit in most cases, and a very great benefit where the serialized data consisted of duplicate strings.
The default WCF binding (basicHttpBinding) was used for all tests, which means the envelope was not encoded into binary. If binaryMessageEncoding was used then all results would be smaller (and the relative difference between the two slightly greater). Duplicate method names were used for all tests so that the envelope size would be the same in all cases.
For protobuf-net results, brackets indicate the byte array was compressed with QuickLZSharp. All SilverlightSerializer results have the compression applied. A List object was used to hold the data in all cases.
10,000 doubles (1-10000):
PB: 32,152 bytes (31,250 bytes)
10,000 strings (“1” – “10000”):
SS: 41,228 bytes
PB: (30,668 bytes)
10,000 strings (all “Hello world”):
SS: 2,760 bytes
PB: 2,137 bytes (594 bytes)
1000,000 strings (“1” – “100000”):
SS: 404,580 bytes
PB: 320,459 bytes (294,408 bytes)
For all tests, protobuf-net consistently resulted in messages at most 73% the size of equivalent compressed SilverlightSerializer messages. I’ve observed that there seems to be a greater reduction with objects smaller than those in the tests described above (approx. 65% based on casual observation).
QuickLZSharp compression consistently improved the message size with both. When applied to protobuf-net serialized data, the level of improvement corresponded with the level of duplication within the data being sent. In a separate project I measured the time it took to apply QuickLZSharp compression to an arbitrary object that was 3,764B before compression. It took 1 ms, and the size was reduced to 3364B. I would suggest that compression is generally worth doing, given the possible improvements. If bandwidth reduction is a priority in a Silverlight Web service then it is worth using compressed protobuf-net serialized byte arrays.
I developed a RichTextEditor control for Silverlight. It inherits from the RichTextBox. It provides properties to get and set text formatting at the carat.
Here is an example of its use. The example is adapted from an official Microsoft sample TextEditor. In the MS sample formatting can be applied to selected text. In my version formatting can be applied on the fly, and the current formatting at the carat (or selection) is shown in the controls. This is more in-line with typical text editors. [The live sample link for the official sample is dead, but the download link works.]
[silverlight: silverlighttexteditor.xap, 950, 600]
Setting the text formatting at the carat was easy. The same code as the official sample worked after removing the condition to check the selection was not of zero length. To get the current formatting I used a SelectionChanged event handler on the control. It finds the attributes of the parent run of Selection.Start:
My initial approach was to use rtb.Selection.GetProperty(dependencyProperty) but this was problematic. It did not always return the expected result when the selection was empty. Accessing dependency properties is also generally slower.
The offical sample allows you to insert UIElements including images. This is for demonstration purposes only, and documents containing such elements cannot be saved. The example I’ve provided leaves these out.
Silverlight RichTextEditor project on Codeplex.
This is a small project I released as open source some time ago. It facilitates programmatic scrolling of a ScrollViewer in Silverlight.
ScrollViewer is a sealed class. Applying the functionality to it via a separate class seems like a neat approach.
Below is an example of its application. The functionality is applied by default in the example. Clicking the off button shows the default behaviour of the ScrollViewer. For convenience, this example is included in the source code download.
The first three buttons on the right set the mode property of the AutoScroller. The ‘New Rectangle’ button adds a shape that may be dragged around the canvas, to demonstrate the autoscrolling functionality.
Automatic scrolling can be set directly also via the ScrollLeft, ScrollUp, SrollRight, ScrollDown properties. Lastly, there are properties to set the scrolling speed and the size of the canvas area that triggers the scrolling in Mode.Drag and Mode.Auto.
Here is an screenshot of an icon button type UserControl I developed in Silverlight:
This shows nine instances of the same UserControl, which is composed of a TextBlock and a panel containing an icon. The content of both of these are specified via properties. The challenge was to enable the panel to be specified declaratively in XAML. The problem was that you can’t use UI elements as static resources in Silverlight. For example, the following approach results in a runtime error:
However, using a TypeConverter, I devised a way to allow the control to be specified like this:
A good general introduction to using Typeconverters with XAML is in Umair Saeed’s blog. The implementation of the TypeConverter class here is adapted from the generic example on that page.
The Icons class just gives a convenient way of referring to the Icons. The code below can return a UserControl, or the root element from it. Note that in the latter case that you need to remove the root element from the created UserControl Instance, or an error will be generated: A UI element cannot be contained in multiple UI elements.
The RectangleIcon class it refers to is a UserControl just containing the Grid with the rectangle.
Lastly, here is how the implementation of the IconPanel property in the IconButton class:
IconHolder is an empty UserControl which will hold the icon. Adding it directly as a child to the root element is also possible – however you need to make sure the names of the panels are different. Otherwise you may try to add a grid named LayoutRoot to another grid named LayoutRoot – which results in the error “Value does not fall within expected range” being thrown at runtime.
When you hover over a UI element and the cursor changes, this is an implementation of the Cursor Invitation design pattern. It indicates to the user that the UI element may be interacted with. The convention is to use it only when the interaction may be non-obvious, so it’s not used with standard buttons.
I was wondering if the convention was to use it with buttons in the form of icons. I couldn’t find anything about it online, so I looked at some Websites using icon-buttons to see what the consensus was. In all examples I found, hand cursors were used for icon buttons. This is logical, since not every icon on every Webpage is interactive. This isn’t consistent with Windows, where the cursor doesn’t change over icons. (This is also logical – every icon in Windows is interactive by default, so the extra prompt is unnecessary.)
It’s very easy to implement this in Silverlight – in both XAML and code-behind. You can just set the cursor property to the hand cursor.Eg:
<Grid x:Name="LayoutRoot" Cursor="Hand">
target.Cursor = Cursors.Hand;
Even better, setting IsEnabled to false stops the cursor change from occurring – so there’s no need to change the cursor property manually when the button is disabled.