How can I format a decimal bound to TextBox without angering my users?

前端 未结 3 1025
陌清茗
陌清茗 2020-12-23 19:20

I\'m trying to display a formatted decimal in a TextBox using data binding in WPF.

Goals

Goal 1: When setting a decimal property in code, display 2 decimal p

3条回答
  •  暖寄归人
    2020-12-23 20:04

    I created the following custom behavior to move the users cursor to after the decimal point when using StringFormat={}{0:0.00}, which forces a decimal place to be present, however this can cause the following issue:

    Violates Goal 2. Say SomeDecimal is 2.5, and the TextBox is displaying "2.50". If we select all and type "13.5" we end up with "13.5.00" in the TextBox because the formatter "helpfully" inserts decimals and zeros.

    I have hacked around this using a custom behavior that will move the users cursor to after the decimal place when they press the . key:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Interactivity;
    
    namespace GUI.Helpers.Behaviors
    {
        public class DecimalPlaceHotkeyBehavior : Behavior
        {
            #region Methods
            protected override void OnAttached()
            {
                base.OnAttached();
                AssociatedObject.PreviewKeyDown += AssociatedObject_PreviewKeyDown;
            }
    
            protected override void OnDetaching()
            {
                base.OnDetaching();
                AssociatedObject.PreviewKeyDown -= AssociatedObject_PreviewKeyDown;
            }
    
            protected override Freezable CreateInstanceCore()
            {
                return new DecimalPlaceHotkeyBehavior();
            }
            #endregion
    
            #region Event Methods
            private void AssociatedObject_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
            {
                if (e.Key == System.Windows.Input.Key.OemPeriod || e.Key == System.Windows.Input.Key.Decimal)
                {
                    var periodIndex = AssociatedObject.Text.IndexOf('.');
                    if (periodIndex != -1)
                    {
                        AssociatedObject.CaretIndex = (periodIndex + 1);
                        e.Handled = true;
                    }
                }
            }
            #endregion
    
            #region Initialization
            public DecimalPlaceHotkeyBehavior()
                : base()
            {
            }
            #endregion
        }
    }
    

    I use it as follows:

    
            
                
            
    
    

提交回复
热议问题