The WPF ah-ha Moment

In nearly every bit of WPF training material or weblog there is some reference to the "ah-ha" moment. The point at which all the new concepts you've been learning gel into a cohesive unit.

For me, that moment was one or two months after I started developing WPF in earnest (by which I mean for users other than myself).

 

The task was to display two different indicators of a business metric, a green up arrow and a red down arrow.

image

My first instinct was to draw the two different arrows, export images to PNG, embed them as resources, and then raise an event each time it changed so that some code behind could dynamically show the appropriate image.

 

So tedious and so not the way to do it.

 

The first realization if there is no image - there is only a shape, or more specifically a Path.

<Path Data="M8,40L8,24 0,24 16,0 32,24 24,24 24,40z"  Stroke="Black"  />

That produced the outline of the arrow.

The next realization was that I could use data binding on Shape properties such as Fill and RotateTransform. My previous mental map around data binding was that it was limited to direct business data, by breaking that model, whole new code-expressive opportunities opened up. And by binding to these newfangled dependency properties - the shape would be updated whenever the properties changed.

 

The first attempt still was too much code, as I assumed I needed a value converter

Fill="{Binding Path=BizMetric, Converter={StaticResource BizMetricToBrushConverter}}"
Again, too tedious and not the way to do it.

My final realization resulted in the code that's in use today, with dependency properties of the type needed directly on the presenter class, and data-bound to the shape

<Path 
     Data="M8,40L8,24 0,24 16,0 32,24 24,24 24,40z" 
     Fill="{Binding Path=BizMetricFillBrush}" 
     RenderTransformOrigin="0.5,0.5" >   
       <Path.RenderTransform>
            <RotateTransform Angle="{Binding Path=BizMetricRotationAngle}"/>
       </Path.RenderTransform>
</Path>

Update:

Russell Mull suggests the use of DataTriggers - which indeed, let you do all the styling in xaml.

<Style TargetType="{x:Type Path}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=BizMetricDirection}" Value="1">
            <Setter Property="Fill" Value="Green" />
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=BizMetricDirection}" Value="0">
            <Setter Property="Fill" Value="Transparent" />
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=BizMetricDirection}" Value="-1">
            <Setter Property="Fill" Value="Red" />
            <Setter Property="RenderTransform">
                <Setter.Value>
                    <RotateTransform Angle="180"/>
                </Setter.Value>
            </Setter>
        </DataTrigger>
    </Style.Triggers>
</Style>

What was your "ah-ha" moment with WPF?

kick it on DotNetKicks.com

2 Comments

Comments have been disabled for this content.