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" />
相关推荐
我要打打代码13 小时前
wpf触发器
java·linux·wpf
The Sheep 202315 小时前
WPF里的几何图形Path绘制
wpf
somethingGoWay16 小时前
wpf 自定义密码文本框,并且可以双向绑定
wpf
玉面小君1 天前
从 WPF 到 Avalonia 的迁移系列实战篇4:控件模板与 TemplatedControl
wpf
何双新1 天前
第 2 讲:Kafka Topic 与 Partition 基础
kafka·wpf·linq
我要打打代码1 天前
WPF依赖属性和依赖属性的包装器:
wpf
cplmlm2 天前
WPF+IOC学习记录
c#·wpf
c#上位机2 天前
wpf之Canvas
c#·wpf
c#上位机2 天前
wpf之样式
c#·wpf