C# WPF - проверка ввода - нельзя использовать десятичные точки (точки) в текстовых полях - PullRequest
0 голосов
/ 26 мая 2020

У меня есть проверка ввода с помощью IDataErrorInfo, но это не позволяет мне использовать десятичные точки (точки) в моем TextBox. Например, попытка ввести 1.222 не работает. Он просто останавливается на 1 и не регистрирует нажатие клавиши . - также нет вывода отладки. Он также все еще пытается принять мой ввод (что вызывает исключение), хотя проверка показывает, что это неправильный формат. Как это исправить?

MainWindow.xaml

<TextBox Text="{Binding Density, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Name="tb_density" Grid.Column="2" HorizontalAlignment="Left" Height="20" Margin="0,4,0,0" Grid.Row="8" TextWrapping="Wrap" VerticalAlignment="Top" Width="140"/>

MainWindow.xaml.cs

private MyViewModel m_ViewModel;
m_ViewModel = new MyViewModel();
DataContext = m_ViewModel;

private void Run_Click(object sender, RoutedEventArgs e) {

    Console.WriteLine("Density: " + (1 * Convert.ToDouble(tb_density.Text))).ToString();
}

MyViewModel.cs

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace foobar{

    class MyViewModel : INotifyPropertyChanged, IDataErrorInfo {

        private double m_density;

        public MyViewModel () {

        }

        public double Density {

            get {

                return m_density;
            }
            set {

                if (m_density!= value) {

                    m_density= value;
                    OnPropertyChanged("Density");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName) {

            if (PropertyChanged != null) {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public string Error {

            get { return "...."; }
        }

        /// <summary>
        /// Will be called for each and every property when ever its value is changed
        /// </summary>
        /// <param name="columnName">Name of the property whose value is changed</param>
        /// <returns></returns>
        public string this[string columnName] {

            get {

                return Validate(columnName);
            }
        }

        private string Validate(string propertyName) {

            // Return error message if there is error on else return empty or null string
            string validationMessage = string.Empty;

            switch (propertyName) {

                case "Density":
                    if(!double.TryParse(Density.ToString(), out _)) {

                        validationMessage = "Error";
                    }
                    break;
            }

            return validationMessage;
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 26 мая 2020

Я думаю, ваша проблема всплывает на поверхность, потому что для UpdateSourceTrigger установлено значение PropertyChanged. Это означает, что каждый раз, когда вы вводите что-либо на клавиатуре, срабатывает проверка ошибок. Таким образом, если вы наберете «1», в настоящее время у вас нет ошибок. Но если вы в следующий раз наберете «.», Теперь у вас будет текстовое поле, содержащее «1». который не пройдет проверку, потому что это не действительное число. Если вы измените UpdateSourceTrigger = LostFocus, он будет оценивать проверку ошибок только после того, как вы покинете текстовое поле.

0 голосов
/ 26 мая 2020

вы можете попробовать что-то, что выглядит следующим образом:

private double _density;
public string Density{
 get => _density.ToString();
 set 
 {
   if(double.TryParse(value, out var density){
     _density = density;
   }
 }

Btw. ваш код, вероятно, не работает из-за if (m_density!= value), когда вы добавляете точку к единице, '1.' по-прежнему равно «1», поэтому значение не обновляется.

...