Dec 16, 2011

Editing Percentages in XAML Part II

Very recently (OK it was yesterday), I wrote up a blog entry on how to show a percentage and edit a percentage without it throwing exceptions or changing by orders of magnitude the backing field. Specifically storing 20% and .2 in the backend (making calculations easier) but showing the user 20% for the field.

Today, I want to share something I learned from StackOverflow member Rachel in her response to my question on why StringFormat=P doesn't work like the StringFormat=C. Rachel prefers to allow editing values in their native format, and after implementing her solution I decided I also preferred this approach. Instead of writing C# code that implements IValueConverter, this approach uses a trigger and all XAML.

The downside to this approach is it isn't as general purpose as having a converter, on the plus side it results in less cluttered XAML at the control location.

The XAML which implements the trigger could go anywhere, since these percentage fields are only used on one form in my solution I just added a <UserControl.Resources> tag at the top of the form and put the relevant XAML there. I'll only show one control, but I needed to replicate this code three times one for each control, modifying the binding in each case.  In the example below you can see I still bind to my CostMarkup property in both cases but when the code is being displayed it adds a StringFormat=P, when the code is being edited there is no formatting so the field changes from 20% to .2. When the user moves off the field the display reverts back to 20%. You'll also notice I incorporated my ctrlSpacingTight style.

Trigger XAML
  1. <UserControl.Resources>
  2.     <Style x:Key="CostMarkupPct"
  3.            TargetType="{x:Type TextBox}"
  4.            BasedOn="{StaticResource ctrlSpacingTight}">
  5.         <Setter Property="Text"
  6.                 Value="{Binding CostMarkup, StringFormat=P}" />
  7.         <Style.Triggers>
  8.             <Trigger Property="IsKeyboardFocused"
  9.                      Value="True">
  10.                 <Setter Property="Text"
  11.                         Value="{Binding CostMarkup}" />
  12.             </Trigger>
  13.         </Style.Triggers>
  14.     </Style>
  15. </UserControl.Resources>

Down in the control XAML I replaced the Style tag and removed both the binding and the associated StringFormat.

<TextBox Style="{StaticResource CostMarkupPct}" />

About Me

My photo
Tod Gentille (@todgentille) is now a Curriculum Director for Pluralsight. He's been programming professionally since well before you were born and was a software consultant for most of his career. He's also a father, husband, drummer, and windsurfer. He wants to be a guitar player but he just hasn't got the chops for it.