title: How can I format a decimal bound to TextBox without angering my users?
body: <p>I'm trying to display a formatted decimal in a TextBox using data binding in WPF.</p>
  <h2>Goals</h2>
  <p>Goal 1: When setting a decimal property in code, display 2 decimal places in the TextBox.</p>
  <p>Goal 2: When a user interacts with (types in) the TextBox, don't piss him/her off.</p>
  <p>Goal 3: Bindings must update source on PropertyChanged.</p>
  <h2>Attempts</h2>
  <p><em><strong>Attempt 1: No formatting.</strong></em></p>
  <p>Here we're starting nearly from scratch.</p>
  <pre><code>&lt;TextBox Text=&quot;{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged}&quot; /&gt;
  </code></pre>
  <p>Violates Goal 1. <code>SomeDecimal = 4.5</code> will show &quot;4.50000&quot; in the TextBox.</p>
  <p><em><strong>Attempt 2: Use StringFormat in the Binding.</strong></em></p>
  <pre><code>&lt;TextBox Text=&quot;{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged, StringFormat=F2}&quot; /&gt;
  </code></pre>
  <p>Violates Goal 2.  Say SomeDecimal is 2.5, and the TextBox is displaying &quot;2.50&quot;.  If we select all and type &quot;13.5&quot; we end up with &quot;13.5.00&quot; in the TextBox because the formatter &quot;helpfully&quot; inserts decimals and zeros.</p>
  <p><em><strong>Attempt 3: use Extended WPF Toolkit's MaskedTextBox.</strong></em></p>
  <p><a href="http://wpftoolkit.codeplex.com/wikipage?title=MaskedTextBox" rel="noreferrer">http://wpftoolkit.codeplex.com/wikipage?title=MaskedTextBox</a></p>
  <p>Assuming I'm reading the documentation correctly, the mask ##0.00 means &quot;two optional digits, followed by a required digit, a decimal point, and two more required digits.  This forces me to say &quot;the largest possible number that can go into this TextBox is 999.99&quot; but let's say I'm ok with that.</p>
  <pre><code>&lt;xctk:MaskedTextBox Value=&quot;{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged}&quot; Mask=&quot;##0.00&quot; /&gt;
  </code></pre>
  <p>Violates Goal 2.  The TextBox starts with <code>___.__</code> and selecting it and typing 5.75 yields <code>575.__</code>.  The only way to get 5.75 is to select the TextBox and type <code>&lt;space&gt;&lt;space&gt;5.75</code>.</p>
  <p><em><strong>Attempt 4: use Extended WPF Toolkit's DecimalUpDown spinner.</strong></em></p>
  <p><a href="http://wpftoolkit.codeplex.com/wikipage?title=DecimalUpDown" rel="noreferrer">http://wpftoolkit.codeplex.com/wikipage?title=DecimalUpDown</a></p>
  <pre><code>&lt;xctk:DecimalUpDown Value=&quot;{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged}&quot; FormatString=&quot;F2&quot; /&gt;
  </code></pre>
  <p>Violates Goal 3.  DecimalUpDown happily ignores UpdateSourceTrigger=PropertyChanged.  One of the Coordinators on the Extended WPF Toolkit Codeplex page suggests a modified ControlTemplate at <a href="http://wpftoolkit.codeplex.com/discussions/352551/" rel="noreferrer">http://wpftoolkit.codeplex.com/discussions/352551/</a>.  This satisfies Goal 3, but violates Goal 2, exhibiting the same behavior as in Attempt 2.</p>
  <p><em><strong>Attempt 5: Using style datatriggers, only use formatting if user is not editing.</strong></em></p>
  <p><a href="https://stackoverflow.com/questions/8183922">Binding to a double with StringFormat on a TextBox</a></p>
  <p>Even if this one satisfied all three goals, I wouldn't want to use it.  (A) Textboxes become 12 lines each instead of 1, and my application contains many, many textboxes.  (B) All my textboxes already have a Style attribute which points to a global StaticResource which sets Margin, Height, and other things.  (C) You may have noticed the code below sets the binding Path twice, which violates the DRY principal.</p>
  <pre><code>&lt;TextBox&gt;
      &lt;TextBox.Style&gt;
          &lt;Style TargetType=&quot;{x:Type TextBox}&quot;&gt;
              &lt;Setter Property=&quot;Text&quot; Value=&quot;{Binding Path=SomeDecimal, StringFormat=F2}&quot; /&gt;
              &lt;Style.Triggers&gt;
                  &lt;Trigger Property=&quot;IsFocused&quot; Value=&quot;True&quot;&gt;
                      &lt;Setter Property=&quot;Text&quot; Value=&quot;{Binding Path=SomeDecimal, UpdateSourceTrigger=PropertyChanged}&quot; /&gt;
                  &lt;/Trigger&gt;
              &lt;/Style.Triggers&gt;
          &lt;/Style&gt;
      &lt;/TextBox.Style&gt;
  &lt;/TextBox&gt;
  </code></pre>
  <p>All these uncomfortable things aside...</p>
  <p>Violates Goal 2.  First, clicking on a TextBox which displays &quot;13.50&quot; suddenly makes it display &quot;13.5000&quot;, which is unexpected.  Second, if starting with a blank TextBox, and I type &quot;13.50&quot;, the TextBox will contain &quot;1350&quot;.  I can't explain why, but pressing the period key doesn't insert decimals if the cursor is at the right end of the string in the TextBox.  If the TextBox contains a string with length &gt; 0, and I reposition the cursor to anywhere except the right end of the string, I can then insert decimal points.</p>
  <p><em><strong>Attempt 6: Do it myself.</strong></em></p>
  <p>I'm about to embark on a jouney of pain and suffering, by either subclassing TextBox, or creating an attached property, and writing the formatting code myself.  It will be full of string manipulation, and cause substantial hairloss.</p>
  <hr />
  <p>Does anyone have any suggestions for formatting decimals bound to textboxes that satisfies all the above goals?</p>