Aktuálně: Postihly zákazy tvou profesi? Poptávka po ajťácích prudce roste, využij slevové akce 50% výuky zdarma!
Pouze tento týden sleva až 80 % na e-learning týkající se Javy

Lekce 2 - Jednoduchá kalkulačka v C# .NET Windows Forms

V minulé lekci, Úvod do Windows Forms aplikací, jsme si uvedli technologii Windows Forms a vytvořili okno s textovým popiskem.

V dnešním C# .NET tutoriálu se podíváme na události a vytvoříme jednoduchou kalkulačku. Bude vypadat takto:

Kalkulačka v C# .NET v oknu

Příprava formuláře

Založte si nový Windows Forms projekt s názvem Kalkulacka. Formulář přejmenujeme na KalkulackaForm. U aplikací se většinou začíná právě návrhem formuláře. Z Toolboxu na něj natáhneme několik ovládacích prvků. Budeme potřebovat:

  • 2x Label
  • 1x Button
  • 2x NumericUpDown
  • 1x ComboBox

Label

Label již známe, jedná se jednoduše o textový popisek.

Pokud ovládací prvky nepoužíváme z kódu, nemusíme je pojmenovávat. Pokud ano, měli bychom jim nastavit vlastnost Name (v oknu Properties je název vlastnosti v závorce (Name)) a přes toto jméno k prvku poté z kódu přistoupíme. Doporučuji si přepnout zobrazení vlastností z kategorizovaného na abecední (první 2 ikonky v Properties oknu), vlastnosti najdete rychleji. Name je tedy jméno objektu, Text je to, co je na objektu napsáno. Z toho logicky vyplývá, že na formuláři můžeme mít více prvků se stejným textem, ale jen jeden s určitým jménem.

Jeden label bude sloužit jen jako popisek s textem "=", nastavte mu ho. Druhý Label bude sloužit pro výpis výsledku a jelikož do něj budeme programově vkládat hodnotu, nastavíme jeho vlastnost Name na vysledekLabel. Text nastavíme na hodnotu "0". Font výsledku můžeme zvětšit na velikost 10.

Button

Button je jednoduše tlačítko, které v případě stisku zavolá nějakou metodu (přesněji vyvolá událost). V našem případě se bude tlačítko jmenovat vypocitejButton a jeho Text bude nastaven na "Vypočítej". Událost tlačítku přiřadíme později.

NumericUpDown

NumericUpDown je první ovládací prvek k zadávání hodnoty, který si uvedeme. Ve výchozím nastavení do něj můžeme zadat jen celé číslo. Toto chování lze změnit nastavením vlastnosti DecimalPlaces, která udává počet desetinných míst. Tuto hodnotu nastavme na 2 oběma ovládacím prvkům. Také nastavíme vlastnosti Minimum a Maximum, v našem případě minimum na nějakou nízkou hodnotu a maximum na nějakou vysokou, např. -1000000 a 1000000. Pokud bychom chtěli využít maximální hodnoty daného datového typu, musíme limity nastavit v kódu formuláře pomocí vlastnosti MaxValue a MinValue na daném datovém typu.

Výhodou zadávání čísel tímto ovládacím prvkem je, že uživatel nemůže zadat nesmyslnou hodnotu. Pokud bychom číslo parsovali z prvku TextBox (který si ukážeme v dalších lekcích), mohla by naše aplikace při nevalidním vstupu spadnout. Je vždy jednodušší vybrat správný ovládací prvek než ošetřovat uživatelský vstup.

Prvky pojmenujeme jako cislo1NumericUpDown a cislo2NumericUpDown. Všimněte si, že jméno by mělo vždy obsahovat i typ ovládacího prvku. Můžeme tak mít např. vekLabel a vekNumericUpDown, kdy label je popisek pole k zadání věku a numericUpDown je potom toto pole. Navíc se v kódu potom lépe orientuje. Někdy se používá i cisloNmr, vypocitejBtn a podobně.

ComboBox

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Jsme skoro v cíli. ComboBox je vyjížděcí seznam s několika předdefinovanými prvky. Prvky můžeme buď naklikat v návrháři nebo vložit z kódu a to i za běhu programu. Toto platí pro všechny komponenty, všechny vlastnosti z návrháře můžeme nastavovat i z kódu. Některé pokročilé vlastnosti jdou však nastavit jen z kódu a v návrháři nejsou.

Ovládací prvek pojmenujeme operaceComboBox a u vlastnosti Items klikneme na tlačítko "...". Do nově otevřeného okna vypíšeme možnosti, které v comboBoxu půjdou vybrat. Každou možnost zapíšeme na samostatný řádek, v našem případě to budou hodnoty +, -, *, /.

Položky ComboBoxu ze C# .NET ve Visual Studio

Položkami nemusí být jen textové řetězce, ale i objekty. Ukážeme si to později.

Vybranou položku lze bohužel nastavit jen z kódu.

Nastavené ovládací prvky uspořádáme na formulář tak, jak bylo uvedeno na začátku článku.

Kód formuláře

Přesuneme se do zdrojového kódu formuláře. Již víme, že to uděláme zkratkou Ctrl + Alt + 0 nebo kliknutím pravým tlačítkem myši na formulář a zvolením možnosti View Code.

V konstruktoru formuláře hned po zavolání InitializeComponents() nastavíme vybranou položku pro operaceComboBox. Uděláme to nastavením vlastnosti SelectedIndex na 0, tedy první položku:

public KalkulackaForm()
{
    InitializeComponent();
    operaceComboBox.SelectedIndex = 0;
}

Z formuláře máme samozřejmě přístup ke všem jeho prvkům.

Do konstruktoru vkládáme ten kód, který se má vykonat po vytvoření formuláře, ale to je snad jasné. Když aplikaci spustíte, bude vybrané sčítání:

Vybrání položky ComboBoxu v C# .NET

Obsluha událostí

Zbývá nám tedy již jen reagovat na událost kliknutí tlačítka. Přesuneme se z kódu zpět na formulář a na tlačítko 2x klikneme. V kódu nám přibyla nová metoda:

private void vypocitejButton_Click(object sender, EventArgs e)
{

}

Pokud jste dočetli zdejší objektový kurz C# .NET, hlavička metody vám bude nápadně připomínat EventHandler. V souboru KalkulackaForm.Designer.cs bychom nalezli kód, který události tlačítka přiděluje právě tuto metodu. Pokud jste předchozím větám nerozuměli, vůbec to nevadí. Bude vám stačit, že se tato metoda spustí v případě, když se na tlačítko klikne.

Vraťme se ještě do designeru (klávesa Shift + F7) a označme tlačítko. V oknu Properties můžeme přepínat mezi vlastnostmi a událostmi a to pomocí níže zvýrazněných tlačítek:

Události ve Visual Studio

Vidíme zde naší událost Click, kterou odsud můžeme odstranit a případně znovu přidat. Některé ovládací prvky mají speciální události, pro které vygenerujeme metody právě odtud.

Nikdy neodstraňujte události tak, že vymažete obslužnou metodu z kódu, designer by přestal fungovat a museli byste jeho soubor opravit (konkrétně odstranit přiřazení neexistující metody do události). Správně je to jedině přes designer.

Výpočet

Přejděme k samotnému výpočtu. Kód nebude nijak složitý, jednoduše v obslužné metodě tlačítka naifujeme vybrané položky operaceComboBox a podle toho vypočítáme výsledek. Ten poté nastavíme jako text vysledekLabel. Neměli bychom zapomenout ošetřit dělení nulou.

Kód obslužné metody by mohl vypadat takto:

private void vypocitejButton_Click(object sender, EventArgs e)
{
    // příprava proměnných
    string operace = operaceComboBox.SelectedItem.ToString();
    double cislo1 = Convert.ToDouble(cislo1NumericUpDown.Value);
    double cislo2 = Convert.ToDouble(cislo2NumericUpDown.Value);
    double vysledek = 0;

    // výpočet
    if (operace == "+")
        vysledek = cislo1 + cislo2;
    else if (operace == "-")
        vysledek = cislo1 - cislo2;
    else if (operace == "*")
        vysledek = cislo1 * cislo2;
    else if (operace == "/")
    {
        if (cislo2 != 0)
            vysledek = cislo1 / cislo2;
        else
            MessageBox.Show("Nulou nelze dělit");
    }
    vysledekLabel.Text = vysledek.ToString();
}

Nejprve si uložíme hodnoty z ovládacích prvků do proměnných, je to tak přehlednější. K vybrané položce comboBoxu se dostaneme přes SelectedItem, který je typu object. V našem případě ho musíme převést na string. Stejně tak bychom mohli pracovat i s pouhým číslem položky přes SelectedIndex. Jelikož NumericUpDown vrací hodnotu ve vlastnosti Value, která je typu decimal, musíme ji převést na double pomocí třídy Convert.

V případě nulového dělitele zobrazujeme uživateli MessageBox pomocí stejnojmenné statické třídy a metody Show(). Nakonec do vysledekLabel vypíšeme výsledek. Na rozdíl od konzole, kde šlo jednoduše vypsat i čísla, zde musíme číslo nejprve převést na string.

Formuláři ještě můžeme nastavit ikonu přes vlastnost Icon (vybereme soubor s ikonkou), Text nastavíme na "Kalkulačka" a StartPosition na CenterScreen. Formulář se tak vytvoří uprostřed obrazovky. Pokud nastavíme FormBorderStyle na hodnotu FixedSingle, nepůjde formulář roztahovat, což se pro naší aplikaci hodí. Stejně tak můžeme zakázat maximalizaci okna pomocí vlastnosti MaximizeBox.

Kód je jako vždy v příloze.

V následujícím cvičení, Řešené úlohy k 1.-2. lekci Windows Forms v C# .NET, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 1554x (108.67 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

Předchozí článek
Úvod do Windows Forms aplikací
Všechny články v sekci
Windows Forms - Okenní aplikace v C# .NET
Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
22 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 13 let. Má rád Nirvanu, sushi a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity (6)

 

 

Komentáře

Avatar
Michal Žůrek - misaz:15.12.2013 12:45

Na vybírání možnosti z comboBoxu se více než hromada ifů hodí switch.

 
Odpovědět
15.12.2013 12:45
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Michal Žůrek - misaz
David Čápka:15.12.2013 12:46

Ify jsou jednodušší a IMHO i přehlednější. Pokud by to mělo být dokonalé, dělalo by se to stejně úplně jinak.

Odpovědět
15.12.2013 12:46
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
petr.zit
Člen
Avatar
petr.zit:28.8.2014 20:04

Zdravicko, prave si prochazim tento tutorial a narazil jsem na problem.

A to že mě se kod zobrazuje uplne jinak než je zde uvedeno. Mam to zrejmne zjednodusene ale nevyznam se v tom mužete mi nekdo rict kde to lze prepnout ?

Díky ...Viz screen

 
Odpovědět
28.8.2014 20:04
Avatar
Odpovídá na petr.zit
Michael Škrášek:28.8.2014 20:09

Založil sis VB project

Odpovědět
28.8.2014 20:09
"I choose a lazy person to do a hard job. Because that person will find an easy way to do it. " Bill Gates
Avatar
Odpovědět
28.8.2014 20:13
"I choose a lazy person to do a hard job. Because that person will find an easy way to do it. " Bill Gates
Avatar
petr.zit
Člen
Avatar
petr.zit:28.8.2014 20:18

Super, díky za Ultra rychlou odpoved. Jsem prekvapen.:O

 
Odpovědět
28.8.2014 20:18
Avatar
brundibar.brun:20.12.2014 13:12

Ahoj potřeboval bych vás poprosit o radu. Kód pro kalkulačku jsem udělal přesně podle návodu akorát mi jakákoli funkce (+,-,*,/) kterou zvolím, dělí. Když v comboboxu zvolím třeba to plus, mínus nebo krát tak to pořád hází podíl. Nevíte kde by mohla být chyba? Jsem začátečník a momentálně se přes to nemůžu přehoupnout. Moc díky :)

 
Odpovědět
20.12.2014 13:12
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na brundibar.brun
Jan Vargovský:20.12.2014 15:08

Dole pod článkem je kód, díky kterého si to můžeš opravit sám. Nebo nám tu budeš muset poslat kousek kódu.

 
Odpovědět
20.12.2014 15:08
Avatar
Odpovídá na Jan Vargovský
brundibar.brun:20.12.2014 15:19

Právě že bych to měl mít úplně stejně jako to má on, už jsem to kontroloval, ale možná že jsem to přehlédnul.
tady to je snad to bude lepší

 
Odpovědět
20.12.2014 15:19
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na brundibar.brun
Jan Vargovský:20.12.2014 16:46

Tak se podívej do designeru, jestli je to opravdu ta komponenta na kterou klikáš. (jestli je comboBox1 opravu ten, který si myslíš)

 
Odpovědět
20.12.2014 16:46
Avatar
Odpovídá na Jan Vargovský
brundibar.brun:20.12.2014 17:32

Právě že je, jinak by to nešlo snad ani spustit. Nemohl bych ti poslat celou složku? Že bys ses na to podíval, jestli bys měl čas?

 
Odpovědět
20.12.2014 17:32
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na brundibar.brun
Jan Vargovský:20.12.2014 18:34

Hoď to na nějaké uložiště a upni to sem.

 
Odpovědět
20.12.2014 18:34
Avatar
Odpovídá na Jan Vargovský
brundibar.brun:20.12.2014 19:01

http://uloz.to/…ication6-zip

Heslo je: meloun
tak na to koukni

 
Odpovědět
20.12.2014 19:01
Avatar
Odpovídá na Jan Vargovský
brundibar.brun:20.12.2014 19:55

už jsem na to přišel, ta poslední podmínka není dobře napsaná ..

 
Odpovědět
20.12.2014 19:55
Avatar
Ota Stránský:25.9.2015 12:31

Ahoj. Měl bych dotaz k tomu mazání eventů u kontrolek. Občas se mi stane, že dvakrát kliknu na Label místo na Button a mám pak v kódu zbytečné nevyužité řádky navíc. Už před čtením článku jsem se sám přesvědčil, že mazat ho nebude ten správný postup. Odstranil jsem tedy událost Labelu v záložce Events (prostě jsem smazal text "label1_Click"). V kódu ale událost zůstala. Je to normální postup nebo se dá kód nějak "zneviditelnit"?

 
Odpovědět
25.9.2015 12:31
Avatar
Odpovídá na Ota Stránský
Patrik Valkovič:25.9.2015 12:38

Událost je v tomto případě pouze obyčerjná funkce. Ale nebude nikde volána, protože se na ni v XAMLu neodkazuješ. Jestliže si callback smazal v XAMLu, můžeš bez problému tuto funkci smazat a program by měl v pořádku fungovat dál.

Odpovědět
25.9.2015 12:38
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Avatar
VLASTIMIL KAMENČÁK:22.10.2015 18:10

zasekl sem se přesně u části Kód formuláře, přiložil sem i obrazovku, mužete mi někdo poradit na co kliknout, nějak dál nevim.

 
Odpovědět
22.10.2015 18:10
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Odpovídá na VLASTIMIL KAMENČÁK
Štefan Pružinský:22.10.2015 18:12

Môžeš sa trochu rozviesť? Rád by so Ti pomohol, ale neviem v čom je vlastne problém. :)

Odpovědět
22.10.2015 18:12
Najefektívnejším spôsobom debuggingu je modlitba. :)
Avatar
VLASTIMIL KAMENČÁK:22.10.2015 19:05

Jsem v části začínající titulkem- kód formuláře
Přesuneme se do zdrojového kódu formuláře. Již víme, že to uděláme zkratkou CTRL + ALT + 0 nebo pravým myšítkem na formulář a View Code. (toto mám viz ten obrázek)

a ted přichází ten zádrhel-

V konstruktoru formuláře hned po zavolání InitializeCom­ponents() nastavíme vybranou položku pro operaceComboBox. Uděláme to nastavením vlastnosti SelectedIndex na 0, tedy první položku:

[public KalkulackaForm()
{
        InitializeComponent();
        operaceComboBox.SelectedIndex = 0;
}

Z formuláře máme samozřejmě přístup ke všem jeho kontrolkám.

Do konstruktoru vkládáme ten kód, který se má vykonat po vytvoření formuláře, ale to je snad jasné. Když aplikaci spustíte, bude vybrané sčítání:

 
Odpovědět
22.10.2015 19:05
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na VLASTIMIL KAMENČÁK
Milan Křepelka:22.10.2015 19:36

Takhle to asi nepůjde Vlasto. Lepší když asi dodáš projekt co máš. Mohl si tam udělat spoustu záležitostí který se takhle slovem nevychytají. Třeba je mi dost divný, proč by se v souboru Form1 měl vyskytovat formulář upSide cosi.

 
Odpovědět
22.10.2015 19:36
Avatar
Štefan Pružinský:22.10.2015 19:39

Stále tomu veľmi nerozumiem...v čom je ten zádrhel? Pokiaľ som tomu správne pochopil, potrebuješ na niečo kliknúť... Načo potrebuješ kliknúť? :)

Odpovědět
22.10.2015 19:39
Najefektívnejším spôsobom debuggingu je modlitba. :)
Avatar
Odpovídá na Štefan Pružinský
VLASTIMIL KAMENČÁK:22.10.2015 20:05

Jak nastavit v konstruktoru formuláře po zavolání InitializeCom­ponents() (to tam mám ještě v pohodě) a nastavit pak operaceComboBox přes vlastnosti SelectedIndex.
Prakticky v kodu nemám- operaceComboBox­.SelectedIndex = 0; a nevím jak to tam dát.
jestli chcete tak je to tady celé:
http://www.fastshare.cz/…ication3.zip

 
Odpovědět
22.10.2015 20:05
Avatar
Odpovídá na VLASTIMIL KAMENČÁK
Štefan Pružinský:22.10.2015 20:31

Ahoj, zrejme si prehliadol tento text:

Pokud kontrolky nepoužíváme z kódu, nemusíme je pojmenovávat. Pokud ano, měli bychom jim nastavit vlastnost Name (v oknu Properties je název vlastnosti v závorce (Name)) a přes toto jméno ke kontrolce poté z kódu přistoupíme. Doporučuji si přepnout zobrazení vlastností z kategorizovaného na abecední (první 2 ikonky v Properties oknu), vlastnosti najdete rychleji. Name je tedy jméno objektu, Text je to, co je na objektu napsáno. Z toho logicky vyplývá, že na formuláři můžeme mít více kontrolek se stejným textem, ale jen jednu s určitým jménem.

V pravom dolnom rohu je okienko s názvom Properties. V tomto okne je roluj dole, kým nájdeš kategóriu Design a v nej hneď prvé nastavenie z názvom (Name). V tomto nastavení prepíšeš ComboBox1 na operaceComboBox. Následne tam vlož ten kód (operaceCombo­Box.SelectedIn­dex = 0;) a spusť. Všetko by malo fungovať ako má. :)
Budem rád, ak Ti moje vysvetlenie pomôže. :)

Odpovědět
22.10.2015 20:31
Najefektívnejším spôsobom debuggingu je modlitba. :)
Avatar
Majký
Člen
Avatar
Majký:1.2.2016 19:52

Nevím, jestli to tu někdo nezmiňoval, ale mě u MVS 2015 Ctrl+Alt+0 nefunguje, ale naopak to jde jednodušeji F7 a zpátky Shift+F7(to už je OK)

 
Odpovědět
1.2.2016 19:52
Avatar
FiftypiSoftware
Super redaktor
Avatar
FiftypiSoftware:8.11.2016 18:31

Zdravím, mám takový dotaz:
je chybou nastavovat hodnoty (např.: Text = "Form2";) v události From2_Load(...)? Když je možné to nastavit v public Form2()?
Je zde nutnost to takhle psát nebo je to jedno?
Čili:

public Form2()
{
        InitializeComponents();
        Text = "Form2";
}

nebo

private void Form2_Load(...)
{
        Text = "Form2";
}

Jen jedno z toho nebo je to jedno? Jak z hlediska funkčnosti?

 
Odpovědět
8.11.2016 18:31
Avatar
jirka.skop
Člen
Avatar
jirka.skop:27.11.2016 10:55

Ahoj,udělal jsem takovou obrácenou kalkulačku(nebo spíš zkoušečku),vy­generuju 2 náhodná čísla,pak vyberu operaci(+,-,atd..),výsledek zapíšu a dalším tlačítkem zkontroluju a objeví se nápis dobře nebo špatně a určitý obrázek.Chtěl bych tam ještě přidat "statistiku"(cel­kový počet,počet dobrých a špatných pokusů),ale nevím jak to spávně pojmenovat a tak nevím na co se mám podívat abych to udělal.A kdyby to nebylo moc složité na začátečníka tak ještě aby se ty obrázky(zmenšená verze) někde zobrazovali,např 5 dobých výsledků = 5 obrázků zobrazených v "něčem"-Nevím v čem to jde zobrazit.Předem díky za rady jak na to.

 
Odpovědět
27.11.2016 10:55
Avatar
Odpovídá na jirka.skop
Michal Štěpánek:28.11.2016 9:14

Záleží na tom, jestli chceš mít tu statistiku přístupnou i po dalším otevření, nebo ne. Pokud ano, bude třeba použít "něco" na ukládání dat, tzn., buď DB nebo soubor (xml, txt, csv...). Pokud chceš mít statistiku jen pro tu instanci otevřeného programu, tzn. že po spuštění programu bude prázdná, pak by ti mělo stačit ukládat data do nějaké kolekce (list, pole...), které program po ukončení "zapomene"...

Odpovědět
28.11.2016 9:14
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Michal Rivola:22.1.2017 11:21

Ahoj, chtěl bych se zeptat proč mi ten výsledek nejde převést na string :D

 
Odpovědět
22.1.2017 11:21
Avatar
Odpovídá na Michal Rivola
Marek Chalupa:22.1.2017 11:39

Hádám, že tam má být Vysledeklabel.Text = vysledek.ToStrin­g();

Samozřejmě jsem zapomněl středník, zlý Python!

Editováno 22.1.2017 11:42
 
Odpovědět
22.1.2017 11:39
Avatar
Odpovídá na Marek Chalupa
Michal Rivola:22.1.2017 11:56

jojo na to už sem přišel :D ale teď zase mi to háže chybu při tý změně ze stringu na double

 
Odpovědět
22.1.2017 11:56
Avatar
Odpovídá na Michal Rivola
Marek Chalupa:22.1.2017 12:03

No, tam ti zase chybí cisloUpDown.Value

 
Odpovědět
22.1.2017 12:03
Avatar
Odpovídá na Marek Chalupa
Michal Rivola:22.1.2017 12:07

ajo :/ sem si tam toho nevšim :D

 
Odpovědět
22.1.2017 12:07
Avatar
Odpovídá na Michal Rivola
Michal Douša:28.1.2019 7:46
Convert.ToDouble(cislo1UpDown.Text);

Pozor! Desetinné číslo chceme udělat pouze z textu té komponenty, nikoliv samotné.

 
Odpovědět
28.1.2019 7:46
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 33 zpráv z 33.