Как вводить текстовые поля в произвольном формате? - PullRequest
1 голос
/ 08 апреля 2020

Как разрешить ввод в текстовое поле только в этом формате?

text

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

Итак, вам нужен TextBox, который принимает:

  • A Di git или цифры, разделенные запятыми и / или ...
  • Диапазон токенов цифр, таких как 1-5 .
  • Каждая цифра / число должны находиться в диапазоне минимальных и максимальных значений.

Давайте создадим для этого собственный текстовый ящик.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace YourNamespace
{
    [DesignerCategory("Code")]
    public class PrintPageRangeTB : TextBox
    {
        public PrintPageRangeTB() : base() { }
//...

Переопределите OnKeyPress способ принятия 0 - 9 , , и - в дополнение к Control клавишам:

//...
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            base.OnKeyPress(e);

            if (!char.IsControl(e.KeyChar) &&
                !char.IsDigit(e.KeyChar) &&
                e.KeyChar != '-' &&
                e.KeyChar != ',')
                e.Handled = true;
        }
//...

Переопределите метод OnTextChanged, чтобы подтвердить ввод, вызвав функцию IsValidInput() и удалить последний введенный символ всякий раз, когда функция возвращает false:

//...
        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);

            if (!IsValidInput())
                SendKeys.SendWait("{BS}");
        }
//...

IsValidInput() Функция проверяет свойство Text и обнаруживает любой недопустимый формат, используя RegEx. Также проверяет минимальные и максимальные значения.

//...
        private bool IsValidInput()
        {
            var parts = Text.Split(new[] { '-', ',' }, 
                StringSplitOptions.RemoveEmptyEntries);
            var pages = parts
                .Where(x => int.TryParse(x, out _)).Select(x => int.Parse(x));

            return !parts.Any(x => x.Length > 1 && x.StartsWith("0")) &&
                !Regex.IsMatch(Text, @"^-|^,|--|,,|,-|-,|\d+-\d+-|-\d+-") &&
                !pages.Any(x => x < Min || x > Max);
        }
//...

Добавьте свойства для назначения минимальных и максимальных значений, свойство, которое возвращает, имеет ли Text допустимый формат, и свойство, которое возвращает выбранные числа. /pages..

//...
        public int Min { get; set; } = 1;
        public int Max { get; set; } = 1000;
        [Browsable(false)]
        public bool IsValidPageRange => TextLength > 0 && IsValidInput();
        [Browsable(false)]
        public IEnumerable<int> Pages
        {
            get
            {
                var pages = new HashSet<int>();

                if (IsValidInput())
                {
                    var pat = @"(\d+)-(\d+)";
                    var parts = Text.Split(new[] { ',' }, 
                        StringSplitOptions.RemoveEmptyEntries);

                    foreach(var part in parts)
                    {
                        var m = Regex.Match(part, pat);

                        if (m != null && m.Groups.Count == 3)
                        {
                            var x = int.Parse(m.Groups[1].Value);
                            var y = int.Parse(m.Groups[2].Value);

                            for (var i = Math.Min(x, y); i <= Math.Max(x, y); i++)
                                pages.Add(i);
                        }
                        else if (int.TryParse(part.Replace("-", ""), out int v))
                            pages.Add(v);
                    }
                }
                return pages.OrderBy(x => x);
            }
        }
//...

Функция, которая соединяет выделение и разделяет их по умолчанию или переданному разделителю:

//...
        public string PagesString(string separator = ", ") =>
            string.Join(separator, Pages);
    }
}

Перестроить, отбросить PrintPageRangeTB из Toolbox , запустите и попробуйте.

SOQ61099950

Вот полный код.


Связанные

  • IP4 TextBox. »

0 голосов
/ 08 апреля 2020

Как уже упоминалось в NeutralHadle, одним из способов является использование маскирования ввода для ограничения возможного ввода.

Другой подход - запускать некоторые логи проверки c при вводе текста, например, путем добавления обработчика событий на валидационное событие. Если текст имеет неправильный формат, вы можете использовать ErrorProviderControl , чтобы сообщить пользователю, как правильно отформатировать ввод. Подробнее в этом ответе .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...