How to allow inputs to the textbox in this format only?
-
1Look up input masking – Peter Dongan Apr 08 '20 at 11:51
-
What kind of app is this? Web, Windows Forms, WPF, something else..? – stuartd Apr 08 '20 at 11:51
-
@stuartd windows form app use c# – TipVisor Apr 08 '20 at 11:52
-
@NeutralHandle how to use input masking? can you give an example – TipVisor Apr 08 '20 at 11:53
-
1https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.maskedtextbox.mask?view=netframework-4.8 – Peter Dongan Apr 08 '20 at 11:57
-
1Not sure this will be possible with a mask. You can though only allow numbers, commas, spaces and hyphens to be typed using the [Keypress](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.keypress) event. – stuartd Apr 08 '20 at 15:19
-
Please explain your format. What does `1-5` mean? Is it a range or DigitDashDigit? What is the minimum and maximum values for each part? Are the signed values permitted? Meanwhile, see if you can imitate [this](https://stackoverflow.com/a/60781845/10216583) solution. – Apr 09 '20 at 00:32
-
@JQSOFT min value 0, max value 1000, An example is the page selection in the Print option on Windows. It's the same thing as selecting pages from a book and printing it all at once. only use numbers & "," & "-" symbols. no need spaces. – TipVisor Apr 09 '20 at 06:48
2 Answers
So you need a TextBox that accepts:
- A Digit or digits separated by commas and/or...
- Range of digits tokens like
1-5
. - Each digit/number should be within the range of minimum and maximum values.
Let's create a custom TextBox for that.
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() { }
//...
Override the OnKeyPress
method to accept 0-9, , and - in addition to the Control
keys:
//...
protected override void OnKeyPress(KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar)
&& !char.IsDigit(e.KeyChar)
&& e.KeyChar != '-'
&& e.KeyChar != ',')
e.Handled = true;
else
base.OnKeyPress(e);
}
//...
Override the OnTextChanged
method to validate the input by calling the IsValidInput()
function and to delete the last entered character whenever the function returns false
:
//...
protected override void OnTextChanged(EventArgs e)
{
if (Text.Trim().Length > 0 && !IsValidInput())
SendKeys.SendWait("{BS}");
else
base.OnTextChanged(e);
}
//...
The IsValidInput()
function validates the Text
property and detects any invalid format using RegEx. Also checks for the minimum and maximum values.
//...
private bool IsValidInput() => IsValidInput(Text);
private bool IsValidInput(string Input)
{
var parts = Input.Split(new[] { '-', ',' },
StringSplitOptions.RemoveEmptyEntries);
var pages = parts
.Where(x => int.TryParse(x, out _)).Select(x => int.Parse(x));
return Input.Trim().Length > 0
&& pages.Count() > 0
&& !parts.Any(x => x.Length > 1 && x.StartsWith("0"))
&& !Regex.IsMatch(Input, @"^-|^,|--|,,|,-|-,|\d+-\d+-|-\d+-")
&& !pages.Any(x => x < Min || x > Max);
}
//...
Add properties to assign the minimum and maximum values, a property that returns whether the Text
has a valid format, and a property that returns the selected numbers/pages..
//...
public int Min { get; set; } = 1;
public int Max { get; set; } = 1000;
[Browsable(false)]
public bool IsValidPageRange => 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);
}
}
//...
A function that joins the selection and separate them by the default or the passed separator:
//...
public string PagesString(string separator = ", ") =>
string.Join(separator, Pages);
}
}
Rebuild, drop a PrintPageRangeTB
from the Toolbox, run and try.
Here's the complete code.
Related
- IP4 TextBox. »
-
After build & i trying import to my project. coming error massage box . "there are no components in MYPATH.....dll that can be placed on the tool box. " what to do that? – TipVisor Apr 11 '20 at 09:27
-
1@TipVisor What error? Just add a new class to your project, paste the code, rebuild. And make sure you change the namespace `YourNamespace` to your project's one. – Apr 11 '20 at 09:30
-
-
1@TipVisor 1) Right click on the project's folder and select Add - Class, name it `PrintPageRangeTB.cs`. 2) Copy the code within the `class PrintPageRangeTB : TextBox { ... }` block and paste it in your new class. 3) Rebuild. 4) Check your Toolbox you'll find it. – Apr 11 '20 at 09:42
-
-
1@TipVisor `string.Join` the `Pages` property like: `TextBox1.Text = string.Join(", ", PrintPageRangeTB1.Pages;`) – Apr 11 '20 at 10:28
-
Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/211424/discussion-between-tipvisor-and-jqsoft). – TipVisor Apr 11 '20 at 10:46
As mentioned by NeutralHadle, one way is to use input masking to restrict the possible input.
Another approach is to run some validation logic when text is entered, for example by attaching an event handler to the Validating event. If the text is in a incorrect format you may then use a ErrorProviderControl to inform the user how to properly format the input. More details in this answer.

- 28,608
- 2
- 10
- 23