wpf 自定义控件,只能输入小数点,并且能控制小数点位数

cs 复制代码
using System.Windows.Input;
using System.Windows;
using System.Windows.Controls;

namespace 项目名称
{
    public class DoubleTextBox : TextBox
    {
        public double? MinValue
        {
            get { return (double?)GetValue(MinValueProperty); }
            set { SetValue(MinValueProperty, value); }
        }

        public static readonly DependencyProperty MinValueProperty =
            DependencyProperty.Register("MinValue", typeof(double?), typeof(DoubleTextBox));

        public double MaxValue
        {
            get { return (double)GetValue(MaxValueProperty); }
            set { SetValue(MaxValueProperty, value); }
        }

        public static readonly DependencyProperty MaxValueProperty =
        DependencyProperty.Register("MaxValue", typeof(double), typeof(DoubleTextBox), new PropertyMetadata(double.MaxValue));

        public static bool GetIsEnabled(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsGotFocusProperty);
        }

        public static void SetIsEnabled(DependencyObject obj, bool value)
        {
            obj.SetValue(IsGotFocusProperty, value);
        }

        public bool IsNeedLoseFucos
        {
            get { return (bool)GetValue(IsNeedLoseFucosvProperty); }
            set { SetValue(IsNeedLoseFucosvProperty, value); }
        }
        public static readonly DependencyProperty IsNeedLoseFucosvProperty =
            DependencyProperty.RegisterAttached("IsNeedLoseFucos", typeof(bool), typeof(DoubleTextBox), new PropertyMetadata(true));

        public bool IsGotFocus
        {
            get { return (bool)GetValue(IsGotFocusProperty); }
            set { SetValue(IsGotFocusProperty, value); }
        }
        public static readonly DependencyProperty IsGotFocusProperty =
            DependencyProperty.RegisterAttached("IsGotFocus", typeof(bool), typeof(DoubleTextBox), new PropertyMetadata(false));

        public string PreviousText
        {
            get { return (string)GetValue(PreviousTextProperty); }
            set { SetValue(PreviousTextProperty, value); }
        }
        public static readonly DependencyProperty PreviousTextProperty =
            DependencyProperty.Register("PreviousText", typeof(string), typeof(DoubleTextBox), new PropertyMetadata(string.Empty));

        public int DecimalCount
        {
            get { return (int)GetValue(DecimalCountProperty); }
            set { SetValue(DecimalCountProperty, value); }
        }
        public static readonly DependencyProperty DecimalCountProperty =
            DependencyProperty.Register("DecimalCount", typeof(int), typeof(DoubleTextBox), new PropertyMetadata(3));

        public string HistoryText
        {
            get { return (string)GetValue(HistoryTextProperty); }
            set { SetValue(HistoryTextProperty, value); }
        }
        public static readonly DependencyProperty HistoryTextProperty = DependencyProperty.Register("HistoryText", typeof(string), typeof(DoubleTextBox), new PropertyMetadata(string.Empty));


        static DoubleTextBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DoubleTextBox), new FrameworkPropertyMetadata(typeof(DoubleTextBox)));
        }

        public DoubleTextBox()
        {
            LostFocus += DoubleTextBox_LostFocus;
            PreviewTextInput += DoubleTextBox_PreviewTextInput;
        }

        private void DoubleTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            Text = Text.Trim();
            string txt = Text + e.Text;

            if (!double.TryParse(txt, out double value))
            {
                if (!string.IsNullOrWhiteSpace(Text))
                {
                    var index = Text.IndexOf(e.Text);
                    if (index > -1) { Text = Text.Remove(index); }

                    SelectionStart = Text.Length + e.Text.Length;
                }
                e.Handled = true; // 阻止输入非数字字符
            }
            else if (value > MaxValue)
            {
                Text = MaxValue.ToString(); // 将文本框的值设置为最大值
                SelectionStart = Text.Length + e.Text.Length;
                e.Handled = true; // 阻止输入超出取值范围的数字
            }
            else if (txt.Contains('.'))
            {
                var Has = txt.Split('.');
                if (Has != null && Has.Length > 0 && Has[1] != null)
                {
                    if (Has[1].Length == DecimalCount)
                    {
                        double dis = double.Parse(txt);
                        if (MinValue is not null && dis < MinValue && txt.Length >= MinValue.Value.ToString().Length)
                        {
                            Text = MinValue.Value.ToString(); // 将文本框的值设置为最小值
                            SelectionStart = Text.Length + e.Text.Length;
                            e.Handled = true; // 阻止输入非数字字符
                        }
                    }
                    else if (Has[1].Length > DecimalCount)
                    {
                        Text = string.Format("{0:f" + DecimalCount + "}", value);
                        double dis = double.Parse(txt);
                        if (MinValue is not null && dis < MinValue && txt.Length >= MinValue.Value.ToString().Length)
                        {
                            Text = MinValue.Value.ToString(); // 将文本框的值设置为最小值
                        }
                        SelectionStart = Text.Length + e.Text.Length;
                        e.Handled = true; // 阻止输入非数字字符
                    }
                }
            }
            else
            {
                Text = value.ToString();
                SelectionStart = Text.Length + e.Text.Length;
                e.Handled = true;
            }
            SelectionStart = Text.Length + e.Text.Length;
            HistoryText = Text;
        }

        private void DoubleTextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            IsGotFocus = false;

            Text = Text.Trim();
            if (string.IsNullOrEmpty(Text))
            {
                if (!string.IsNullOrEmpty(HistoryText) && double.TryParse(HistoryText, out double history) && history > MinValue)
                {
                    Text = HistoryText;
                }
                else if(!string.IsNullOrEmpty(PreviousText))
                {
                    Text = PreviousText;
                }
                else if (MinValue is not null)
                {
                    Text = MinValue.Value.ToString();
                }
                SelectionStart = Text.Length;
            }
            else
            {
                if (double.TryParse(Text, out double num))
                {
                    if (num < MinValue)
                    {
                        if (!string.IsNullOrEmpty(HistoryText) && double.TryParse(HistoryText, out double history) && history > MinValue)
                        {
                            Text = HistoryText;
                        }
                        else
                        {
                            Text = MinValue.ToString();
                        }
                    }
                    else if (num > MaxValue)
                    {
                        if (!string.IsNullOrEmpty(HistoryText) && double.TryParse(HistoryText, out double history) && history < MaxValue)
                        {
                            Text = HistoryText;
                        }
                        else if (!string.IsNullOrEmpty(PreviousText))
                        {
                            Text = PreviousText;
                        }
                        else
                        {
                            Text = MaxValue.ToString();
                        }
                    }
                }
            }
        }
    }
}

调用:DecimalCount就是小数点位数,一般不去设置,最多三位小数点。如果失去焦点,当前的数据会时你上次输入的数据,这样不会出现数据为空的情况。

cs 复制代码
 xmlns:local="clr-namespace:你的项目名"  
        xmlns:sys="clr-namespace:System;assembly=mscorlib"  

<local:DoubleTextBox MinValue="0.001" MaxValue="1000000000" PreviousText="1" Text="{Binding Dilution,TargetNullValue={x:Static sys:String.Empty}}" 
                                 Width="183" Height="60" MaxLength="10" />
相关推荐
KmSH8umpK1 天前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第三篇
redis·分布式·wpf
KmSH8umpK1 天前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案
redis·分布式·wpf
武藤一雄1 天前
WPF:MessageBox系统消息框
前端·microsoft·c#·.net·wpf
武藤一雄1 天前
WPF进阶:万字详解WPF如何性能优化
windows·性能优化·c#·.net·wpf·.netcore·鲁棒性
wangnaisheng1 天前
【WPF】路由事件详细使用
wpf
雨浓YN2 天前
GKMLT通讯工具箱(WPF MVVM) - 07-倍福ADS通讯
网络·wpf
雨浓YN2 天前
GKMLT通讯工具箱(WPF MVVM) - 04-三菱MC通讯
wpf
不会编程的懒洋洋2 天前
WPF XAML+布局+控件
xml·开发语言·c#·视觉检测·wpf·机器视觉·视图
雨浓YN2 天前
GKMLT通讯工具箱(WPF MVVM) - 06-OPCUA通讯
wpf
雨浓YN2 天前
GKMLT通讯工具箱(WPF MVVM) - 03-西门子S7通讯
wpf