Mike Strobel’s WPF Blog

I’ve been working with Mike Strobel for several weeks now at my current client.  He is an amazingly able WPF developer who has been plugging away at the technology since the days when we were still calling it Avalon (I must say, I really prefer the Microsoft code-names for their technologies to the utilitarian acronyms they eventually morph into – for instance, isn’t the “Atlas” moniker much superior to “ASP.NET AJAX”).

A day doesn’t go by that I don’t look at his code and have a small mental epiphany usually accompanied by the mumbled statement “I didn’t know you could do that with WPF.…”

After a bit of encouragement Mike has finally started blogging.  The first post is an explication of his history with WPF and the various ways he is currently using it.  One of the interesting things he reveals is that he not only is doing both game development and enterprise development using WPF, but that he is able to apply techniques he discovers (invents?) in one domain to the other.

You can find Mike’s blog here: http://codedreams.blogspot.com .

I hope that over the next few weeks you will be as blown away as I have been with the remarkable things he has been able to do on the WPF platform.

A UI Design Pattern Love Song

Much has been written about the MVC but never, I believe, a love song … so here you go: a love song to the Model-View-Controller. 

This small experiment in erotic didacticism is sung to Some Enchanted Evening from Rogers and Hammerstein’s South Pacific.  I have embedded a video of Ezio Pinza and Mary Martin singing the original in case you need some help with the tune.

Some enchanted evening
You may see a pattern,
you may see a pattern
Across a crowded room
And somehow you know,
You know even then
That somewhere you’ll see it
Again and again.

Model-View-Controller
Someone may be coding
You may hear him coding
Across a crowded room
And night after night,
As strange as it seems
The shape of that pattern
Will drift through your dreams.

Who can explain it?
Who can tell you why?
Fools give you reasons,
Wise men never try.

Model-View-Controller
First it has a model,
Yes it has a model
To represent your store,
It’s your data store
Your persistence layer
Where all of your data
Is written and saved.

Model-View-Controller
Has a presentation,
And that presentation
Of state is called a View.
A view of your store
On your GUI layer
It’s bound to your model
And registers change.

Model-View-Controller
Third has a controller
That facilitates
Changes to model state
On your model layer
In response to acts
That come from your user
With keyboard or mouse.

Once you understand it,
Never let it go.
Once you understand it,
Never let it go!

Synchronizing Style Hierarchies with Control Hierarchies in WPF

WPF provides two ways to apply styles to control elements: by name and by type.  In the typical named style implementation, one declares both the name by which a style can be referenced as well as the control type to which it can be applied.  For instance, a style declaration for a ComboBox would look like this:

<Style x:Key="ComboBoxStyle" TargetType="ComboBox">
    ...
</Style>

When styles are applied in this way, the underlying WPF rendering mechanism understands type hierarchies.  Consequently, this style could also be written with a TargetType higher up in the Control type hierarchy and still work:

<Style x:Key="ComboBoxStyle" TargetType="Control">
   ...
</Style>

This is a handy feature when you want to build a custom control but want to preserve your styles.  For instance, the ComboBox control has no built-in ability to trigger commands.  If you want to use MVVM, however, this is quite a shortcoming.  You can overcome this problem by building a custom control based on the ComboBox type and implementing the ICommandSource interface to pick up the SelectionChanged event:

class CustomComboBox: ComboBox, ICommandSource
{
     ...
}

Since my CustomComboBox inherits from the WPF ComboBox, the named style I use with a TargetType of ComboBox will automatically be applied to it and the following XAML:

<Window x:Class="SampleWPFProject.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=System"
    xmlns:custom="clr-namespace:SampleWPFProject"
    Title="Window1" Height="300" Width="300">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="25"/>
        <RowDefinition Height="25"/>
    </Grid.RowDefinitions>
    <StackPanel Grid.Row="0" Name="stackPanel1" Orientation="Horizontal">
        <TextBlock Margin="0,0,10,0" Width="60">Employees</TextBlock>
        <ComboBox x:Name="cbEmployees" SelectedIndex="0" Width="200" 
                  Style="{StaticResource ComboBoxStyle}">
            <ComboBoxItem>John Adams</ComboBoxItem>
            <ComboBoxItem>Ben Franklin</ComboBoxItem>
            <ComboBoxItem>Pat Henry</ComboBoxItem>
        </ComboBox>
    </StackPanel>
    <StackPanel Grid.Row="1" Name="stackPanel2" Orientation="Horizontal">
        <TextBlock Margin="0,0,10,0" Width="60">Tasks:</TextBlock>
        <custom:CustomComboBox x:Name="cbTasks" SelectedIndex="0" Width="200" 
                   Style="{StaticResource ComboBoxStyle}">
            <ComboBoxItem>Write Constitution</ComboBoxItem>
            <ComboBoxItem>Write Declaration</ComboBoxItem>
            <ComboBoxItem>Go for a ride</ComboBoxItem>
        </custom:CustomComboBox>
    </StackPanel>
</Grid>
</Window>

will fortuitously render itself like this, with the nice curvy boarders specified in my “ComboBoxStyle” style definition:

styleSample

But what if I want to apply my custom style arbitrarily to all ComboBoxes in my application?  This is where typed styles are very handy.

I can change the “key” element of the ComboBoxStyle to apply it generically to all ComboBoxes like this:

<Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
   ...
</Style>

Inside my XAML, I would simply remove the reference to the named style:

<ComboBox x:Name="cbEmployees" SelectedIndex="0" Width="200">
   ...
<custom:CustomComboBox x:Name="cbTasks" SelectedIndex="0" Width="200">

Unfortunately, the typed style does not understand that my CustomComboBox inherits from the ComboBox type, and the rendered window looks like this, reverting to the default ComboBox styling for my custom class:

 styleExample2

I could simply copy the entire original style and create a new one that specifies the CustomComboBox as the key, instead.  There is a shorter way, however.  I can take advantage of the BasedOn attribute of the style resource.  Rather than copy the entire style, I will create a new style based the original style and set the key to our custom type:

<Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
   ...
</Style>

<Style BasedOn="{StaticResource {x:Type ComboBox}}"  
       x:Key="{x:Type custom:CustomComboBox}" 
       TargetType="ComboBox"/>

Typically the BasedOn attribute is used to extend a base style with certain changes: for instance, off of a base style that sets  Button backgrounds to blue, one might want to create another that overrides the background color and sets it to orange.

This example shows that it can be used in a rather different way, however, to take a pre-existing typed style and apply it to a different type.  In this particular case, it is being used to align custom styles that are part of an inheritance hierarchy with custom controls that are part of a related type hierarchy.

Should it become necessary to extend the CustomComboBox control with a new custom control, in turn, one should be prepared to similarly extend the style hierarchy using the BasedOn attribute in order to maintain synchronization between one’s presentation and one’s functionality.