IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

5. diel - Code Behind v C # .NET WPF a dokončenie kalkulačky

V minulej lekcii, Návrh formulára pre kalkulačku v C # .NET WPF , sme nakódovali formulár pre jednoduchú kalkulačku. Dnes v C# .NET tutoriálu do aplikácie pridáme jednoduchú logiku a na konci si vysvetlíme ako WPF vnútri funguje.

Code Behind

Prezentačná časť aplikácie je napísaná v XAML. Ten nám však samozrejme nestačí a preto má každé okno okrem XAML kódu ešte tzv. Code Behind (kód na pozadí), ktorý obsahuje volania logiky aplikácie. Do tohto kódu sa z dizajnérov presunieme pravým kliknutím myši a zvolením možnosti View Code. Alternatívne môžeme používať klávesové skratky Ctrl + Alt + 0 (jedná sa o nulu na alfanumerickej klávesnici) pre presun do Code Behind a Shift + F7 na presun do grafického návrhára.

Code Behind nášho formulára vyzerá asi takto (vynechal som menné priestory):

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}

Vidíme, že formulár je reprezentovaný triedou, ktorá dedí z Window. Window je trieda, predstavujúce prvok Window. Každý ovládací prvok má vo WPF má svoju triedu, ako inak v objektovom jazyku :) V konstruktoru formuláre sa volá záhadná metóda InitializeComponents(), ktorá vnútorne naparsuje XAML a vytvorí podľa neho inštancie jednotlivých prvkov. Tým sa formulár "zostaví".

Pomenovanie ovládacích prvkov

Keď chceme s nejakým prvkom pracovať z Code Behind, musíme mu priradiť meno. Staršie verzie Graphic Designeri ovládacie prvky nepojmenovávaly vôbec, neskoršie je začali číslovať ako TextBlock1 a podobne. V našom prípade budeme pri výpočte potrebovať čítať z dvoch elementov TextBox s číslami, elementu ComboBox s operáciou, písať do TextBlock s výsledkom a obslúžiť udalosť kliknutí na tlačidlo.

Presunieme sa späť do XAML a týmto prvkom zmeníme (v starších VS pridáme) atribút Name s nasledujúce hodnotou pre jednotlivé prvky: cislo1TextBox, cislo2TextBox, operaceComboBox, vysledekTextBlock, vypocitejButton. Všimnite si, že mená sme zvolili tak, aby končila typom ovládacieho prvku. Pri väčších formulároch je to oveľa prehľadnejšie. Určite sa vyvarujeme názvom ako tlacitko1 a podobne.

Udalosti

WPF sú postavené na udalostiach. My budeme v kalkulačke reagovať na jedinú udalosť, ktorou je kliknutie na tlačidlo. V dizajnéri na tlačidlo poklepeme, budeme presmerovaní na Code Behind, kde sa nám vygeneruje nasledujúce metóda:

private void vypocitejButton_Click(object sender, RoutedEventArgs e)
{
}

Metóda sa spustí vo chvíli, keď na tlačidlo používateľ klikne. Ako zastáva docielené sa dozvieme neskôr. Udalosti môžeme priraďovať a mazať tiež v oknu Properties. Stačí prvok označiť a kliknúť na ikonu blesku, čím sa presunieme z vlastností do udalostí. Tlačidlo vedľa nás potom presunie späť na vlastnosti:

Udalosti vo WPF v C# .NET Visual Studio - Okenné aplikácie v C # .NET WPF

Do vygenerované metódy vložme nasledujúci kód:

// příprava proměnných
string operace = operaceComboBox.Text;
double cislo1 = double.Parse(cislo1TextBox.Text);
double cislo2 = double.Parse(cislo2TextBox.Text);
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");
}
vysledekTextBlock.Text = vysledek.ToString();

Na prvých riadkoch si pripravíme premenné, do ktorých uložíme potrebné hodnoty z ovládacích prvkov. K textu v TextBox UIK vybranej textovej položke ComboBox u sa dostaneme cez vlastnosť Text. Vidíme tu, prečo sme prvky pomenovávali. V aplikácii nijako neriešime situáciu, kedy užívateľ zadá nezmyselný vstup a program tak spadne na výnimku pri parsovanie tejto hodnoty. Ako sa správne ošetrujú chyby si ukážeme až v ďalších lekciách, môžete sa sem potom vrátiť a validáciu dodať.

Výpočet výsledku by mal byť jasný. Zaujímavá je tu len kontrola, či nedelíme nulou. Ak áno, zobrazíme tzv. MessageBox, čo je okno so správou pre užívateľov, ktoré určite dobre poznáte z iných aplikácií. Slúži nám k tomu rovnomenná statická trieda. MessageBox vyzerá asi takto:

MessageBox v C# .NET - Okenné aplikácie v C # .NET WPF

Na konci metódy už len priradíme do TextBlock u výsledok, ktorý musíme previesť na string, pretože priraďujeme do vlastnosti Text.

Môžete si aplikáciu vyskúšať.

Kompletné kalkulačka v C# .NET WPF - Okenné aplikácie v C # .NET WPF

WPF pod pokrievkou

Než začneme zas pokročilejšie látku, venujme niekoľko odsekov tomu, ako aplikácia funguje pod pokrievkou. Je to trochu taká teória navyše, ak ste nedočítali tunajšie objektový C# .NET kurz do konca, asi nebudete všetkému rozumieť, v praktickom vytváranie aplikácií vám to však nebude nijako brániť.

Parciálny trieda

Zamerajme sa ešte raz na triedu MainWindow (teda na Code Behind). Bystrejší z vás si iste všimli, že trieda je parciálny (má modifikátor partial). To znamená, že je definovaná vo viacerých súboroch. Tá druhá chýbajúcu časť je skrytá a môžeme do nej prejsť tak, že klikneme na volanie metódy InitializeComponent() a stlačíme F12, čo nás prenesie k jej implementáciu.

Dostali sme sa do pomerne škaredé triedy, ktorú nám Visual Studio samo vygenerovalo s novým oknom. Vidíme tu dve metódy: InitializeComponent () a Connect ().

  • InitializeComponent() si načíta XAML a zavolá na neho LoadComponent(). Všimnite si nad triedou atribútov zo menného priestoru CodeDom. Tu sú triedy pre generovanie C# kódu za behu aplikácie. Presne to metóda robí, dekóduje XAML a vytvára inštancie ovládacích prvkov podľa ich definície v XAML.
  • Metóda Connect() sprostredkováva ono magické napojenie metód v Code Behind. Vidíme tu, že je použitý EventHandler:
vypocitejButton.Click += new System.Windows.RoutedEventHandler(this.vypocitejButton_Click);

Metóda ďalej sprístupňuje jednotlivé ovládacie prvky pod ich názvami, to je realizované tým škaredým switchom :) Do tohto súboru nebudeme nikdy nijako zasahovať, je však dôležité, aby sme chápali, ako WPF funguje.

Vytváranie ovládacích prvkov za behu aplikácie

Keďže ovládacie prvky sú obyčajné triedy, určite vás napadlo, či ich môžeme na formulár pridávať tak, že vytvoríme ich inštancie v Code Behind namiesto toho, aby sme ich písali do XAML. Áno, ide to. Teoreticky by sme XAML kód nemuseli vôbec používať. Prakticky by sme sa však v návrhu formulárov vôbec nevyznali.

Ukážme si nejakú časť nášho XAML, napr. Grid. Ten vyzerá takto:

<Grid Margin="0">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="50"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="50"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="30"/>
    </Grid.RowDefinitions>
</Grid>

V Code Behind by sme rovnaký výsledok dosiahli týmto zápisom:

Grid grid = new Grid();
grid.Margin = ((Thickness)(TypeDescriptor.GetConverter(typeof(Thickness)).ConvertFromInvariantString("0")));
ColumnDefinition columnDefinition = new ColumnDefinition();
columnDefinition.Width = ((GridLength)(TypeDescriptor.GetConverter(typeof(GridLength)).ConvertFromInvariantString("*")));
grid.ColumnDefinitions.Add(columnDefinition);
ColumnDefinition columnDefinition2 = new ColumnDefinition();
columnDefinition2.Width = ((GridLength)(TypeDescriptor.GetConverter(typeof(GridLength)).ConvertFromInvariantString("50")));
grid.ColumnDefinitions.Add(columnDefinition2);
ColumnDefinition columnDefinition3 = new ColumnDefinition();
columnDefinition3.Width = ((GridLength)(TypeDescriptor.GetConverter(typeof(GridLength)).ConvertFromInvariantString("*")));
grid.ColumnDefinitions.Add(columnDefinition3);
ColumnDefinition columnDefinition4 = new ColumnDefinition();
columnDefinition4.Width = ((GridLength)(TypeDescriptor.GetConverter(typeof(GridLength)).ConvertFromInvariantString("50")));
grid.ColumnDefinitions.Add(columnDefinition4);
ColumnDefinition columnDefinition5 = new ColumnDefinition();
columnDefinition5.Width = ((GridLength)(TypeDescriptor.GetConverter(typeof(GridLength)).ConvertFromInvariantString("*")));
grid.ColumnDefinitions.Add(columnDefinition5);
RowDefinition rowDefinition = new RowDefinition();
rowDefinition.Height = ((GridLength)(TypeDescriptor.GetConverter(typeof(GridLength)).ConvertFromInvariantString("*")));
grid.RowDefinitions.Add(rowDefinition);
RowDefinition rowDefinition2 = new RowDefinition();
rowDefinition2.Height = ((GridLength)(TypeDescriptor.GetConverter(typeof(GridLength)).ConvertFromInvariantString("30")));
grid.RowDefinitions.Add(rowDefinition2);

Asi uznáte, že to nie je práve prehľadné a to sa jedná o malú časť formulára. Takže práve preto sa používa XAML, kde je stromová štruktúra prehľadná a jednoduchá.

Niekedy však môže byť naopak užitočné vytvoriť nejakú časť aplikácie alebo niečo donastaviť až v Code Behind miesto v XAML. Účelom tejto časti kurzu bolo, aby ste vedeli, že to ide.

V budúcej lekcii, Riešené úlohy k 1.-5. lekciu WPF v C # .NET , začneme tvoriť robustnejšie aplikáciu, pôjde o pripomienkovej narodenín priateľov. Zdrojové kódy kalkulačky sú ako vždy na stiahnutie nižšie.

V nasledujúcom cvičení, Riešené úlohy k 1.-5. lekciu WPF v C # .NET, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 819x (400.42 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Predchádzajúci článok
Návrh formulára pre kalkulačku v C # .NET WPF
Všetky články v sekcii
Okenné aplikácie v C # .NET WPF
Preskočiť článok
(neodporúčame)
Riešené úlohy k 1.-5. lekciu WPF v C # .NET
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
2 hlasov
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity