Letní akce PHP týden
Pouze tento týden sleva až 80 % na kurzy PHP. Lze kombinovat s akcí Letní slevy na prémiový obsah!
Brno? Vypsali jsme pro vás nové termíny školení Základů programování a OOP v Brně!
Avatar
Filip Němec
Člen
Avatar
Filip Němec:11. ledna 23:39

Ahoj vespolek :)

Mám WPF projekt, kde je nějaký textBox a metodu ve vlastní třídě:

public static bool IsDigit(Key key)
       {
           Key[] keys = {
               Key.NumPad0,
               Key.NumPad1,
               Key.NumPad2,
               Key.NumPad3,
               Key.NumPad4,
               Key.NumPad5,
               Key.NumPad6,
               Key.NumPad7,
               Key.NumPad8,
               Key.NumPad9,
               Key.D0,
               Key.D1,
               Key.D2,
               Key.D3,
               Key.D4,
               Key.D5,
               Key.D6,
               Key.D7,
               Key.D8,
               Key.D9
           };
           return keys.Contains(key);
       }

Na formuláři pak událost:

private void TimeInput_KeyDown(object sender, KeyEventArgs e)
        {
            if (!InputManager.IsDigit(e.Key))
                e.Handled = true;
        }

Problém samozřejmě nastává ve chvíli, kdy D0 - D9 jsou pouze KeyCodes a nejedná se o hodnoty. Takže mi pak projde: +ěščřžýáíé.

Zkusil jsem: Znamená to tedy, že by asi pole keys mělo obsahovat i shift (aby prošla první podmínka). A dále jsem zkusil přetížit metodu:

public static bool IsDigit(Key key, bool isShiftPressed)
       {
           Key[] keys = {
               Key.NumPad0,
               Key.NumPad1,
               Key.NumPad2,
               Key.NumPad3,
               Key.NumPad4,
               Key.NumPad5,
               Key.NumPad6,
               Key.NumPad7,
               Key.NumPad8,
               Key.NumPad9,
               Key.LeftShift,
               Key.D0,
               Key.D1,
               Key.D2,
               Key.D3,
               Key.D4,
               Key.D5,
               Key.D6,
               Key.D7,
               Key.D8,
               Key.D9
           };
           if (isShiftPressed && keys.Contains(key))
               return true;
           return false;
       }
private void TimeInput_KeyDown(object sender, KeyEventArgs e)
        {
            if (!InputManager.IsDigit(e.Key))
                e.Handled = true;

            if (Keyboard.IsKeyDown(Key.LeftShift))
            {
                //nevím, jak dál
            }
        }

Dále nastává problém, kdy bude přepnuto na anglickou klávesnici a tím pádem shift nepotřebuji a čísla by měla fungovat.

Chci docílit: Snažím se dosáhnout toho, aby do textBoxu šla zadat pouze číslice. Všechna na numerické klávesnici a dále všechna pod klávesami F1-F12. Se shiftem v CZ a bez shiftu v ENG. Dokázal by mi někdo poradit, jak na to? Předem děkuji za pomoc :)

 
Odpovědět 11. ledna 23:39
Avatar
Kenvil
Člen
Avatar
Odpovídá na Filip Němec
Kenvil:12. ledna 0:43

Podle mě by si měl porovnávat jak shift tak zvolenou klávesu

if (Keyboard.IsKeyDown(Key.LeftShift) &&  Keyboard.IsKeyDown(Key.D0) || Keyboard.IsKeyDown(Key.D1) ..... )

a pak nějakou podmínku které bude porovnávat jestli se opravdu jedná o číslo a pokud ne tak aby v případě stisknutí příslušných kláves znak nahradilo za číslo, shift + d1 otestovat pokud by se nejednalo o číslo nahradí to číslem 1 atd

 
Nahoru Odpovědět 12. ledna 0:43
Avatar
Filip Němec
Člen
Avatar
Odpovídá na Kenvil
Filip Němec:12. ledna 0:54

Myšlenka dobrá, ale moc se mi nelíbí, že by to byla taková mega podmínka. Napadlo mě ještě, jak by to možná šlo jednoduše a zbavit se tak toho, že je jedno, na co mačkám a jakou mám klávesnici.

V té události něco jako:

private void TimeInput_KeyDown(object sender, KeyEventArgs e)
        {
            if (!int.TryParse(KeyValue, out k))
                e.Handled = true;
        }

Ale nevím, jak získat value té klávesy.

 
Nahoru Odpovědět 12. ledna 0:54
Avatar
simon.steiner:12. ledna 12:25

Zkus použít PreviewTextInput event.

private void TimeInput_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
        if (!int.TryParse(e.Text, out _))
                e.Handled = true;
}
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět  +1 12. ledna 12:25
Avatar
ostrozan
Redaktor
Avatar
Odpovídá na simon.steiner
ostrozan:13. ledna 13:36

Proč hned parsovat?
Stačí použít přesně stejnou metodu jakou použil IsDigit() - jen tu z třídy Char.
Ta vrací true, pokud znak je číslice.

if(Char.IsDigit(e.Text)) e.handled = true ;
 
Nahoru Odpovědět  +3 13. ledna 13:36
Avatar
Filip Němec
Člen
Avatar
Odpovídá na ostrozan
Filip Němec:13. ledna 17:39

Já mám ale celý string textboxu, nikoli char.

 
Nahoru Odpovědět 13. ledna 17:39
Avatar
Filip Němec
Člen
Avatar
Filip Němec:13. ledna 17:59

Tudíž místo dvou řádků bych musel mít něco jako:

char[] characters = e.Text.ToCharArray();
            foreach (char c in characters)
            {
                if (!char.IsDigit(c))
                    e.Handled = true;
            }

Proč to dělat jednoduše, když to jde složitě? :)

 
Nahoru Odpovědět 13. ledna 17:59
Avatar
Odpovídá na Filip Němec
Michael Škrášek:13. ledna 19:51

Jde to mnohem jednodušeji:

if (e.Text.Any(char.IsDigit))
        ...
Nahoru Odpovědět  +2 13. ledna 19:51
I choose a lazy person to do a hard job. Because that person will find an easy way to do it ... Bill Gates
Avatar
ostrozan
Redaktor
Avatar
Odpovídá na Filip Němec
ostrozan:13. ledna 19:57

Událost PrewiewTextInput ti zachytává každou změnu textu - a tou změnou je vlastně jeden jediný - poslední zadaný znak.
Kontroluje tedy to, co přijde z klávesnice, ještě před tím, než se to zapíše do textu TextBoxu.

To

e.Handled = true ;

vlastně zabrání tomu, aby se ten znak z klávesnice připojil k textu TextBoxu.

Teď si uvědomuju, že podmínku jsem napsal špatně a má vypadat takto:

if (!char.IsDigit(e.Text, 0)) e.Handled = true;
 
Nahoru Odpovědět  +1 13. ledna 19:57
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 9 zpráv z 9.