Diskuze: c# form - testování čísla pomocí Regex
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 16 zpráv z 16.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Trošku postrádám smysl tvého počínání. Kdybys použil NumericUpDown, nemusel bys nic testovat...
U numericUpDown jsou postraně šipky a ty já tam nechci. A nevím jestli
jdou nějak zřušit. A hlavně u numericUpDown mohu zadat jakékoliv číslo a
až když stisknu enter (tab...) tak to teprve vyhodnotí a vloží maximální
číslo. Já jsem to chtěl udělat testování již při zadávání proto
událost keypress a textbox.
Pokud by to šlo lépe udělat přes numericUpDown napiš mi prosím jak.
Díky
Edit: tak skrývání šipek u numericUpDown jsem už pořešil:
numericUpDown1.Controls[0].Hide();
Vzhledem k tomu, že NumUpDown v podstatě nedovolí napsat nic jiného, než číslo, tak není co testovat...
Já jsem to chtěl udělat testování již při zadávání proto událost keypress a textbox.
Pokud bys to přeci jen chtěl testovat při zadávání, měla by tam být nějaká událost "textchanged", nebo tak něco a v ní bych kontroloval, jestli je to číslo nebo ne...
tohle ti ošetří že do textBoxu se ti nezapíše nic jiného, než požadované znaky - nemusíš mazat a opravovat
private void textBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
string characters="0123456789,";
if (!characters.Contains(e.Text)) e.Handled = true;
}
a tímhle ošetříš max hodnotu
if(float.Parse(TextBox.Text)>999.99) VyhodChybu();
omlouvám se - přehlédl jsem "form" v titulku - ten PrewiewTextInput je samozřejmě jen ve WPF, ale to druhé platí
const string supportedchars = "0123456789,\b";
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (0 > supportedchars.IndexOf(e.KeyChar)) e.KeyChar = '\0';
}
private void NecoProved(float f)
{
Text = f.ToString();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
float f;
if (float.TryParse(textBox1.Text, out f) && f < 1000) NecoProved(f);
else NecoProved(0);
}
Se správným regulárním výrazem to jde provést i takto
Neřeším validaci při opuštění pole, kdy může na konci zůstat
oddělovací čárka, je to jen nástřel
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if(e.KeyChar != (char)Keys.Back)
{
var textBox = (sender as TextBox);
var newText = textBox.Text.Remove(textBox.SelectionStart, textBox.SelectionLength).Insert(textBox.SelectionStart, e.KeyChar.ToString());
e.Handled = !Regex.IsMatch(newText, @"^\d*(\,(\d{0,2})?)?$");
}
}
Ahoj,
tak jsem se k tomu konečně dostal. Nakonec jsem to vyřešil takto a vypadá,
že to funguje tak jak jsem chtěl:
private void textBox3_KeyPress(object sender, KeyPressEventArgs e)
{
char insertedChar = e.KeyChar;
if ((insertedChar == 44) && (textBox3.Text.IndexOf(',') != -1))
{
e.Handled = true;
return;
}
if ((!Char.IsDigit(insertedChar)) && (insertedChar != 8) && (insertedChar != 44))
{
e.Handled = true;
}
if (Char.IsNumber(e.KeyChar))
{
float f;
int positionCursor = textBox3.SelectionStart;
string newNum = textBox3.Text.Insert(positionCursor, e.KeyChar.ToString());
if ((float.TryParse(newNum, out f)) && (f > 999.99) || (Regex.IsMatch(newNum, "^\\d*\\,\\d{3}$")))
{
e.Handled = true;
}
}
}
Uživatel nemůže vložit větší číslo než 999,99 a pouze jednu
desetinnou čárku a jen čísla. A vše testuji hned při zadávání, takže v
textBoxu se větší nebo jiné znaky nezobrazují.
Děkuji všem za pomoc a hlavně inspiraci. Akorát teď nevím komu přiřknout
"Akceptované řešení", protože jsem čerpal od všech
ale takto nemáš ošetřeno vložení textu ze schránky. Doporučuji kombinovat KeyPress s TextChanged, nebo i filtrovat schránku
Ahoj, díky za radu na vložení textu ze schránky jsem zapomněl. Zkusím
to nějak napravit přes událost TextChanged. Jak filtrovat schránku??
Ještě jsem se tě chtěl zeptat jak si myslel NumberDecimalSeparator vůbec
tuto metodu neznám.
Díky
Tak vkladaní přes ctrl+v nebo kontextové menu jsem vyřešil takto:
private void textBox3_KeyPress(object sender, KeyPressEventArgs e)
{
char insertedChar = e.KeyChar;
if ((insertedChar == 44) && (textBox3.Text.IndexOf(',') != -1))
{
e.Handled = true;
return;
}
// Testuji zda neni vlozeny znak cislo a zda neni backspace a zda neni carka (',') a zda neni vlozeno ctrl+v, pokud neni ani jedno znak nezobrazuji v textBoxu
if ((!Char.IsDigit(insertedChar)) && (insertedChar != 8) && (insertedChar != 44) && (insertedChar != 22))
{
e.Handled = true;
}
if (Char.IsNumber(e.KeyChar)) // Testuji zda je vlozeny znak cislo
{
float f;
int positionCursor = textBox3.SelectionStart; // Zjistim pozici, kde byl vlozen posledni znak
string newNum = textBox3.Text.Insert(positionCursor, e.KeyChar.ToString()); // Spojim jiz vlozene cislo v textBoxu s nove vlozenym znakem na pozici kurzoru
if ((float.TryParse(newNum, out f)) && (f > 999.99) || (!Regex.IsMatch(newNum, @"^\d*(\,(\d{0,2})?)?$")))
{
e.Handled = true;
}
}
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
string insertedNum = textBox3.Text;
float f;
if ((float.TryParse(insertedNum, out f)) && (f > 999.99) || (!Regex.IsMatch(insertedNum, @"^\d*(\,(\d{0,2})?)?$")))
{
textBox3.Text = "";
MessageBox.Show("Muzete vlozit pouze cislo od 0 do 999,99!!");
}
}
V události KeyPress jsem povolil stisk ctrl+v a pak v události TextChanged
znovu testuji vložené číslo.
Zatím to funguje jak má
regex vůbec neovládám, takže pokud na tom trváš, tak si to budeš muset upravit:
using System;
using System.Windows.Forms;
using System.Globalization;
namespace WindowsFormsApplication17
{
public partial class Form1 : Form
{
const string supportedchars = "0123456789\b";
//nepřemýšlím nad tim, že by mohl být dec. separ. i řetězec
readonly char dseparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0];
public Form1()
{
InitializeComponent();
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == dseparator)
{
if (textBox1.Text.Length == 0 || textBox1.Text.IndexOf(dseparator) > -1) e.KeyChar = '\0';
}
else if (0 > supportedchars.IndexOf(e.KeyChar)) e.KeyChar = '\0';
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.Text.Length > 0)
{
float f;
if (float.TryParse(textBox1.Text, out f) && f >= 0 && f <= 999.99) NecoProved(f);
else textBox1.Clear();
}
}
//nějaká metoda, která zpracovává vyhodnocené číslo
private void NecoProved(float f)
{
Text = f.ToString();
}
}
}
To filtrování schránky je asi zbytečné, stejně uživatel by uživatel mohl zadat velké číslo např. dodatečným umazáním desetinné čárky. Takže nejlépe bude ošetřit událost TextChanged.
Díky... Už jsem to úspěšně dořešil.
Děkuji všem za pomoc a hlavně inspiraci.
Zobrazeno 16 zpráv z 16.