Friday, May 30, 2008

JSONized query strings

I often have to Response.Redirect to an ASP.NET page that takes a lot of parameters. There are a few ways of doing this. One way might be to invoke the page with a query string that contains the parameters:
Foo.aspx?a=66&b=77

If you think of the query string parameters as bunch of properties on a class then you could easily see how one might author that class to also serialize and deserialize the query string by leveraging StringBuilder.Append or String.Format and String.Split etc etc.

I’ve been working with Microsoft AJAX recently and I'd used the text based JSON serializer a couple of times and it got me thinking about how I might leverage that to serialize my object properties to and from the query string. [The XmlSerializer might seem like another approach, but ASP.NET really doesn’t like angle brackets (even encoded) sent as data in the query string – it barfs in case you were wondering with a ‘that data looks very suspicious’ type message.]

So I decided to give the JSON parser a whirl and it works like a charm. Here’s what my JSON encoded query string looks like:

Foo.aspx?qps={"A":66,"B":77}

Here's the class:


Here's the caller:


Here's the callee:


I *always* wrap the FromJSON call in a try / catch block in case someone tries to send a hacked query string that clearly won’t deserialize.

Monday, May 05, 2008

Creating 'Expression Blend' ScrollBars in WPF

The scroll bars in Expression Blend are very nice. Nice enough that I thought I’d spend some time this afternoon figuring out how I could modify the WPF scroll bar control template. Fortunately, it turned out that there really wasn’t that much work involved. Here’s the result:



I started off by grabbing the template from
MSDN. The scroll bar template consists of a style that brings into play either the VerticalScrollBar template or the HorizontalScrollBar template via the Orientation dependency property as seen:



The remaining discussion will only focus on the VerticalScrollBar, since the solution is almost exactly the same for HorizontalScrollBar.

The RepeatButton defined in the VerticalScrollBar template seen at Grid="0" and again at Grid="2" defines the up arrow and down arrow respectively. I made these a little more elongated to mirror the Blend arrows by changing the content properties as follows:

Top arrow: Content="M 0 8 L 8 8 L 4 0 Z"
Bottom arrow: Content="M 0 0 L 4 8 L 8 0 Z"



The scroll thumb also needed some attention. The shape of the thumb at both ends is more rounded than the default, so I increased the CornerRadius:
CornerRadius="4"

Also, the thumb in blend has no border, so I removed the BorderBrush and set the:

BorderThickness="0"

Another difference is that the thumb is highlighted when the mouse is over it and changes colour to black while it is being dragged. Both of these are dependency properties that can be modified to the appropriate values with triggers:




Notice that I had to give the Border a name ‘roundedBorder’ so that the triggers could reference it.

ScrollBarLineButton defines the style and template for the repeater button that houses the arrows (which will end up being up or down for vertical scroll bar. And left or right for a horizontal scroll bar). The template for ScrollBarLineButton acquires the visual for the arrow by databinding to the Content property of the template parent – a neat trick that means only one ScrollBarLineButton needs to be defined for the whole template to be able to deal with all four arrows.


To get the ScrollBarLineButton to look like the blend version, I had to make a few more changes. The arrow is highlighted when the mouse is over it – in much the same way as the thumb. To achieve this, I gave the Path a name ‘glyph’ and then changed the trigger ‘IsMouseOver’ to retarget to ‘glyph’ Fill to the colour: GlyphMouseOver. The IsPressed trigger also needs to mirror the thumb and sets the ‘glyph’ Fill to black.



Finally, I also had to change some of the brushes defined for the scrollbar. Here are the changed versions:
<SolidColorBrush x:Key="GlyphBrush"Color="#FF7E7C7C" />
<SolidColorBrush x:Key="GlyphMouseOver"Color="#FFE8E8E8"/>
<SolidColorBrush x:Key="PressedBrush" Color="Black"/>
<SolidColorBrush x:Key="NormalBrush"Color="#585858"/>