[ CallMeSaMaster @ 22.11.2009. 11:46 ] @
Pozdrav,

imam jedan textBox na formi koji sam ogranicio na unos samo brojeva, backspace-a i zareza. Htio bih dodatno da napravim ogranicenje da se nakon
zareza mogu unijeti maximalno dvije decimale.

Recimo ne zelim da moze da se unese vrijednost 3,265, ali da se moze unijeti 3,26 ili samo 3,2. Moze li mi neko primjer dati ili neki link?

Hvala


T
[ DarkMan @ 22.11.2009. 13:08 ] @
Code:

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    TextBoxBase textBox = sender as TextBoxBase;
    // dozvola: ctrl+x (24), ctrl+c (3), ctrl+v (22)
    if((int)e.KeyChar == 3 || (int)e.KeyChar == 22 || (int)e.KeyChar == 24) return;
    // zarez tretiraj kao tacku
    if(e.KeyChar == ',') e.KeyChar = '.';
    // dozvoli unos: brojava, znak minus, tacka i backspace
    if(!Char.IsDigit(e.KeyChar) && e.KeyChar != '-' && e.KeyChar != '.' && e.KeyChar != (char)Keys.Back) e.Handled = true;
    // dozvoli samo jednu tacku
    if(e.KeyChar == '.' && textBox.Text.Contains(".")) e.Handled = true;
    // dozvoli samo dve cifre nakon tacke (cifre se i dalje mogu dodavati pre tacke)
    if(Char.IsDigit(e.KeyChar) && textBox.Text.Contains(".") && (textBox.Text.Length - textBox.Text.IndexOf('.')) > 2 && textBox.SelectionStart > textBox.Text.IndexOf('.')) e.Handled = true;
    // dozvoli znak minus samo na pocetku
    if(e.KeyChar == '-' && textBox.SelectionStart != 0) e.Handled = true;
}


Ovo i dalje ne sprecava da korisnika pastuje tekst koji nije u zeljenoj formi. I ako se ukloni prvi red kojim se dozvoljavaju tastaturne precice za cut/copy/paste korisnik i dalje moze da koristi meni koji je dostupan desnim klikom misa na TextBox.
[ CallMeSaMaster @ 23.11.2009. 15:06 ] @
Pozdrav,

hvala za ovu pomoc ali imam jos jedno pitanjce:

Kako mogu da provjerim da li je neko uopce unio cijeli broj ili neki broj sa zarezom?
Npr. da li neko unio samo broj 5? U tom slucau bih ja htio da mi se onLeave eventu utomatski dodaju nule.

Znaci ja unesem recimo 5 ali kad se izgubi focus s tog TextBoxa, da mi se u njemu automatski upise 5,00. Znaci samo u slucaju da nemam broj sa zarezom...
[ Igor Gajic @ 23.11.2009. 15:42 ] @
Ceo broj - ima 0 decimalnih tacaka
Float - ima tacno 1 decimalnih tacaka


i samo proveris

textBox1.Text.Contains('.') u Leave dogadjaju...
[ Cola @ 23.11.2009. 18:50 ] @
u Leave dogadjaju...
Code:

      decimal broj;
      if (decimal.TryParse(textBox1.Text, out broj))
      { 
        textBox1.Text = broj.ToString("N2")
      }
[ Dejan Carić @ 23.11.2009. 19:56 ] @
Nije dobro da korisniku zabraniš unos određenih karaktera bez ikakvog feedback-a.
Mnogo je bolje da mu omogućiš unos svih karaktera, a da posle na neki event uradiš validaciju unetog teksta i da korisniku prikažeš poruku ako tekst nije validan. Kao što DarkMan reče, validacija na key_press event-u se veoma lako preskače.

Da bi napravio validaciju gde se može uneti pozitivan ili negativan broj na max. 2 decimale, gde se za decimalni zarez koristi znak ( , ), možeš iskoristiti sledeći regex pattern.
Code:
^[-]{0,1}[\d]+([,]{0,1}[\d]{1,2}){0,1}$

Moguće da mi se potkrala neka greška.

Vodi računa o tome da se za decimalni zarez može koristiti zarez ili tačka. To zavisi od regional setting-a, pa možeš pogledati CultureInfo klasu.
[ CallMeSaMaster @ 24.11.2009. 08:05 ] @
Ok shvatio sam, ali ovo je samo neka test app tako da znam sigurno postavke regional settings-a i mislim da mi nece praviti problem.

Moze li mi neko reci sledece: Imam npr. 10 TextBoxova i htio bih da dodam za svaki Leave EventHandler. Medjutim ne zelim da za svaki TextBox kreiram po jedan Handler nego da dinamicki u codu dodajem hendlere. Recimo da ce se broj boxova s vremenom mijenjat pa ne zelim stalno brisat boxove sa forme.

Ja sam napravio sledece:

Code:
   private void FormData_Load(object sender, EventArgs e)
            {
                foreach (Control c in MyControls.Controls)
                {
                    if (c.GetType().FullName == "System.Windows.Forms.TextBox")
                    {

                        TextBox textBoxControl = (TextBox)c;
                        textBoxControl.Leave += new EventHandler(textBoxControl_Leave);

                    }
                }
            }


Sada sam dodao method koji hendla ovo:

Code:

            private void textBoxControl_Leave(object sender, EventArgs e)
            {
                decimal broj;

                if (decimal.TryParse(????????.Text, out broj))
                {
                    ????????.Text = broj.ToString("N2");
                }
            }


Problem su mi ovi upitnici jer ne znam kako da pristupim toj kontroli odnosno kako da setujem vrijednost Texta u tim boxovima.

Moze li mi neko reci da li ovo moze ovako i kako da uradim taj pristup?

Hvala svima
[ Cola @ 24.11.2009. 08:17 ] @
ovako
Code:


            private void textBoxControl_Leave(object sender, EventArgs e)
            {
                decimal broj;
                TextBox myTb = (TextBox)sender;
                if (decimal.TryParse(myTb.Text, out broj))
                {
                    myTb.Text = broj.ToString("N2");
                }
            }


[Ovu poruku je menjao Cola dana 24.11.2009. u 09:33 GMT+1]
[ CallMeSaMaster @ 24.11.2009. 08:42 ] @
Hvala , ovo radi.
[ DarkMan @ 24.11.2009. 12:33 ] @
Kada imas vise TextBox kontrola za koje hoces istu funkcionalnost onda ne bi bilo lose napraviti modifikovanu verziju TextBox kontrole koju ces koristit umesto regularne verzije.

Na primer:

Code:

    [ToolboxItem(true)]
    [ToolboxBitmap(typeof(TextBox))]
    public class TextBoxDecimal: System.Windows.Forms.TextBox
    {
        private int m_Decimals = 2;
  
        [Description("Decimal values to display.")]
        [DefaultValue(2)]
        public int Decimals
        {
            get { return m_Decimals; }
            set { this.m_Decimals = value; }
        }

        public TextBoxDecimal()
        {
            base.TextChanged += new EventHandler(TextBoxDecimal_TextChanged);
            base.Enter += new EventHandler(TextBoxDecimal_Enter);
            base.Leave += new EventHandler(TextBoxDecimal_Leave);
            base.KeyPress += new KeyPressEventHandler(TextBoxDecimal_KeyPress);
        }

        private void TextBoxDecimal_TextChanged(object sender, EventArgs e)
        {
            ...
        }

        private void TextBoxDecimal_Enter(object sender, EventArgs e)
        {
            ...
        }

        private void TextBoxDecimal_Leave(object sender, EventArgs e)
        {
            ...
        }


        private void TextBoxDecimal_KeyPress(object sender, KeyPressEventArgs e)
        {
            ...
        }
    }

[ peka @ 24.11.2009. 15:41 ] @
A zasto jednostavno ne koristis NumericUpDown kontrolu? Ona radi sve to sto ti je potrebno: unos decimalnog broj (sa tackom ili zarezom u zavisnosti od regional settings-a na racunaru), min i max vrijednost i broj decimala. A i ne moras posle da parsujes unijetu vrijednost, nego je samo procitas kao Decimal (numericUpDown1.Value).
[ night-shift @ 25.11.2009. 19:10 ] @
^ Solidno rešenje.

Možeš i da ukloniš UpDown dugmiće na toj komponenti. Napraviš novu klasu koja će naslediti NumericUpDown:

Code:
namespace Neki
{
    class MojTextBox : System.Windows.Forms.NumericUpDown
    {

        public MojTextBox() { Controls[0].Visible = false; }
    }
}


Postaviš običan NumericUpDown na formu i onda u Form1.Designer.cs fajlu zameniš NumericUpDown sa MojTextBox i dobićeš ga na formi.