4. NejvetsiZe3CiselWPF

4.4. C#

V souboru MainWindow.xaml.cs obsahující kód na pozadí (Code Behind) byla vygenerována základní struktura našeho programu v C# s konstruktorem MainWindow stejnojmenné částečné třídy MainWindow. Tělo konstruktoru obsahuje pouze metodu InitializeComponent(). Dále byly vygenerovány soukromé (private) metody bez návratu:

  • TxtA_GotFocus
  • TxtB_GotFocus
  • TxtC_GotFocus
  • TxtA_LostFocus
  • TxtB_LostFocus
  • TxtC_LostFocus
  • BtnPorovnej1_Click
  • BtnPorovnej2_Click
  • BtnPorovnej3_Click
  • BtnPorovnej4_Click
  • BtnPorovnej5_Click
  • BtnKonec_Click

Všechny tyto události začleníme do regionu Události - viz Kód 1. Počáteční značku (#region Události) umístíme před první metodu obsluhy tlačítka a koncovou značku (#endregion) za poslední metodu obsluhy tlačítka.

#region Události
 
#endregion

Kód 1: Deklarace regionu s názvem Události

V následujícím kódu vidíme popisek statické třídy Constants, včetně její datové složky, jenž představuje konstantní textový řetězec s názvem ZadCislo, ve kterém je uložena hodnota (text) "Zadejte číslo" - viz Kód 2.

/// <summary>
/// Statická třída obsahující deklaraci textové konstanty
/// </summary>
static class Constants
{
    // Deklarace a inicializace datové složky třídy
    public const string ZadCislo = "Zadejte číslo";
}

Kód 2: Deklarace statické třídy Constants s veřejně přístupnou datovou konstantní textovou složkou 

Takto deklarovanou statickou třídu využijeme v konstruktoru (metoda pro tvorbu formuláře) k vypsání textu "Zadejte číslo" v prvcích pro zadání celých čísel - viz Kód 3. Znamená to, že v prvcích na formuláři bude po spuštění aplikace vypsán stejný text. K datové složce statické třídy (v našem případě textové konstantě) přistoupíme pomocí tečkové notace uvedené za statickou třídou.

// Konstruktor třídy
public MainWindow()
{
    InitializeComponent();
    // Při spuštění aplikace je vypsán text v prvcích pro čísla
    TxtA.Text = Constants.ZadCislo;
    TxtB.Text = Constants.ZadCislo;
    TxtC.Text = Constants.ZadCislo;
}

Kód 3: Deklarace konstruktoru třídy

V první metodě pro obsluhu události zacílení (GotFocus) objektu TxtA typu TextBox, sloužící pro zadání prvního porovnávaného čísla, vytvoříme kód, který bude pomocí podmínky if detekovat, zda při přepnutí na objekt obsahuje počáteční text "Zadejte číslo". Pokud ano, vymažeme tento text, aby uživatel mohl jednoduše zadat číslo (jedná se o číslice) - viz Kód 4. Stejným způsobem budeme definovat těla metod TxtB_GotFocus, TxtC_GotFocus. 

// Vymazání počátečního textu v objektu pro první číslo
private void TxtA_GotFocus(object sender, RoutedEventArgs e)
{
    // Pokud je umístěn počáteční text "Zadejte číslo" v objektu pro první číslo 
    if (this.TxtA.Text == Constants.ZadCislo)
    {
        // Vymazání textu v objektu pro první číslo
        this.TxtA.Text = string.Empty;
    }
}

Kód 4: Deklarace metody pro zacílení objektu prvního čísla (TxtA_GotFocus)

Další metodou, kterou budeme specifikovat, je obsluha opuštění objektu porovnávaného čísla na formuláři (událost LostFocus). Pokud objekt neobsahuje číslo (text ve formě číslic), nebo pokud nelze konvertovat (metoda TryParse) zadané číslice na celé číslo, které uložíme do lokální celočíselné proměnné a, vyplníme objekt textem "Zadejte číslo". V podmínce příkazu if použijeme logický součet - disjunkce mezi dvěma částmi podmínky (operátor ||) , který znamená nebo - viz Kód 5. Obdobným způsobem budeme definovat těla metod TxtB_LostFocus a TxtC_LostFocus.

// Vyplnění počátečního textu v objektu pro první číslo při opuštění prázdného objektu
private void TxtA_LostFocus(object sender, RoutedEventArgs e)
{
    // Pokud objekt prvního čísla neobsahuje text, nebo nelze konvertovat text na číslo
    if ((this.TxtA.Text == string.Empty) || (int.TryParse(this.TxtA.Text, out int a) == false))
    {
        // Vyplnění objektu textem "Zadejte číslo"
        this.TxtA.Text = Constants.ZadCislo;
    }
}

Kód 5: Deklarace metody pro opuštění objektu prvního čísla (TxtA_LostFocus)

Asi jste si všimli, že výstupní celočíselný parametr a, není předán do další metody, která by s ním pracovala. Mělo by být naší snahou redukovat počet proměnných, protože každá proměnná představuje kousek paměti počítače, který je pro ní rezervován, abychom do něj mohli ukládat hodnoty. V případě metody TryParse nepotřebujeme s proměnnou a dále pracovat, nebo ji někam dále předávat. To zajistíme v jiné metodě. Proto je možné nahradit deklaraci proměnné int a za klíčovým out podtržítkem _ - viz Kód 6. Tento operátor představuje zástupnou proměnnou, do níž není zapotřebí ukládat hodnotu (v angličtině naleznete vysvětlení pod pojmem Discards). Toto nahrazení zástupnou proměnnou lze v jazyce C# používat od verze 7.0.

int.TryParse(this.TxtA.Text, out _) == false

 Kód 6 - Konverze se zástupnou proměnnou (hodnota není uložena do výstupní proměnné)

Následující kód obsahuje tělo první metody pro obsluhu události Click tlačítka BtnPorovnej1 - viz Kód 7. V začátku metody jsou deklarovány 3 celočíselné proměnné, jejichž hodnoty jsou načteny z prvků na formuláři. Tyto hodnoty jsou načteny pomocí vlastnosti Text vyvolané pomocí tečkové notace u prvku. Načtená hodnota představuje textový řetězec (datový typ string), proto je zapotřebí hodnotu konvertovat na celé číslo pomocí metody TryParse vyvolané pomocí tečkové notace u datového typu int. Výstupním parametrem této metody je příslušná proměnná, tzn. konvertovaná hodnota je uložena do proměnné. Pro porovnání čísel je použito vnořené rozhodování umístěné přímo v metodě. 

// Metoda bez návratu pro porovnání 3 čísel - vnořené rozhodování
private void BtnPorovnej1_Click(object sender, RoutedEventArgs e)
{
    /* Deklarace lokálních proměnných: 'a' ... první celé číslo; 'b' ... druhé celé číslo;
     * 'c' ... třetí celé číslo */
    int a, b, c;
 
    // Konverze textu na číslo a uložení do proměnné 'a'
    int.TryParse(TxtA.Text, out a);
    int.TryParse(TxtB.Text, out b);
    int.TryParse(TxtC.Text, out c);
 
    // Porovnání prvního a druhé čísla
    if (a > b)
        // Vnořené rozhodování
        if (a > c)
            // Výpis názvu maxima a hodnoty maxima do dialogového okna
            MessageBox.Show("Největší je a = " + a);
        else
            if (a == c)
                MessageBox.Show("Největší je a = c = " + a);
            else
                MessageBox.Show("Největší je c = " + c);
    else
        if (a == b)
            if (b > c)
                MessageBox.Show("Největší je a = b = " + a);
            else
                if (b == c)
                    MessageBox.Show("Největší je a = b = c = " + a);
                else
                    MessageBox.Show("Největší je c = " + c);
        else
            if (b > c)
                MessageBox.Show("Největší je b = " + b);
            else
                if (b == c)
                    MessageBox.Show("Největší je b = c = " + b);
                else
                    MessageBox.Show("Největší je c = " + c);
}

Kód 7: Deklarace metody pro porovnání 3 celočíselných hodnot - vnořené rozhodování (BtnPorovnej1_Click)

Dalším přístupem při hledání maxima ze 3 zadaných čísel je využití kaskádování rozhodovacích podmínek s využitím logického součinu - konjunkce (a zároveň, tj. operátor &&) uvedeného v podmínce - viz Kód 8. Výpis je zajištěn v dialogovém oknu.

// Metoda bez návratu pro porovnání 3 čísel - kaskádování (pomocí spojování podmínek)
private void BtnPorovnej2_Click(object sender, RoutedEventArgs e)
{
    // Deklarace lokálních proměnných: 'a', 'b', 'c' ... tři celá čísla
    int a, b, c;
 
    // Konverze textu na číslo a uložení do proměnné 'a'
    int.TryParse(TxtA.Text, out a);
    int.TryParse(TxtB.Text, out b);
    int.TryParse(TxtC.Text, out c);
 
    // Spojení dvou podmínek pomocí 'a zároveň'
    if (a > b && a > c)
        // Výpis názvu maxima a hodnoty maxima do dialogového okna
        MessageBox.Show("Největší je a = " + a);
    else 
        if (a > b && a == c)
            MessageBox.Show("Největší je a = c = " + a);
        else 
            if (a > b && a < c)
                MessageBox.Show("Největší je c = " + c);
            else 
                if (a == b && a > c)
                    MessageBox.Show("Největší je a = b = " + a);
                else 
                    if (a == b && a == c)
                        MessageBox.Show("Největší je a = b = c = " + a);
                    else 
                        if (a == b && a < c)
                            MessageBox.Show("Největší je c = " + c);
                        else 
                            if (a < b && b > c)
                                MessageBox.Show("Největší je b = " + b);
                            else 
                                if (a < b && b == c)
                                    MessageBox.Show("Největší je b = c = " + b);
                                else 
                                    if (a < b && b < c)
                                        MessageBox.Show("Největší je c = " + c);
                                    else
                                        MessageBox.Show("Někde je chyba!");
}

Kód 8: Deklarace metody pro porovnání 3 celočíselných hodnot - kaskádování s využitím logické spojky (BtnPorovnej2_Click)

Před region Výpočty deklarujeme metodu s celočíselným návratem VetsiRovno, která bude provádět návrat většího čísla z předaných čísel (nebo rovné druhému) - viz Kód 9. Oba parametry jsou předány hodnotou. Další možností zápisu těla metody je využít ternární operátor, kde jak vidíte, zápis se vejde na jednu řádku (tento kód je zakomentován, tzn. nebude vykonán).

/// <summary>
/// Metoda s celočíselným návratem většího čísla ze dvou přijímaných čísel
/// </summary>
/// <param name="x"> první celé číslo předané hodnotou </param>
/// <param name="y"> druhé celé číslo předané hodnotou </param>
/// <returns> maximum ze dvou čísel </returns>
private int VetsiRovno(int x, int y)
{
    // Pokud je první předané číslo větší, nebo rovno druhému...
    if (x >= y)
 
        // Metoda navrací první číslo
        return x;
    // Jinak...
    else
        // Metoda navrací druhé číslo
        return y;
 
    // Jiný způsob řešení pomocí ternárního operátoru
    //return (a >= b ? a : b); 
}

Kód 9: Deklarace soukromé metody s návratem s názvem VetsiRovno

Deklarovanou metodu s návratem budeme následně dvakrát volat v metodě bez návratu pro obsluhu události kliknutí na tlačítko BtnPorovnej3 - viz Kód 10. V metodě jsou deklarovány kromě lokálních proměnných a, b a c další lokální proměnné max, které reprezentuje maximum získané dvojitým voláním metody s návratem VetsiRovno. V prvním volání této metody je použit jako první parametr výsledek z dalšího volání této metody, který představuje vetší číslo z čísel uložených v a a b. Další lokální proměnnou je textový řetězec s (datový typ string), do kterého vložíme počáteční text "Největší je ". Pak k tomuto textu připojíme název maxima včetně jeho hodnoty na základě výsledku testu rovnosti z jednotlivých podmínek.

// Metoda bez návratu pro porovnání 3 čísel - volání metody s návratem
private void BtnPorovnej3_Click(object sender, RoutedEventArgs e)
{
    // Deklarace lokálních proměnných: 'a', 'b', 'c' ... tři celá čísla
    int a, b, c;
    /* Deklarace: 'max' ... hodnota největšího čísla (maxima); 
     * 's' ... text výsledného výpisu */
    int max;
    string s = "Největší je ";
 
    // Konverze textu na číslo a uložení do proměnné 'a'
    int.TryParse(TxtA.Text, out a);
    int.TryParse(TxtB.Text, out b);
    int.TryParse(TxtC.Text, out c);
 
    // Získání hodnoty maxima - první parametr je maximum z čísel 'a' a 'b'
    max = VetsiRovno(VetsiRovno(a, b), c);
 
    // Pokud je první číslo rovno maximum...
    if (a == max)
        // První číslo je maximem
        s += ("a = ");
    // Pokud je druhé číslo rovno maximum...
    if (b == max)
        // Druhé číslo je maximem
        s += ("b = ");
    // Pokud je třetí číslo rovno maximum...
    if (c == max)
        // Třetí číslo je maximem
        s += ("c = ");
    // Výpis názvu maxima a hodnoty maxima
    MessageBox.Show(s + max);
}

Kód 10: Deklarace metody pro porovnání 3 celočíselných hodnot - volání metody s návratem VetsiRovno (BtnPorovnej3_Click)

Ve čtvrté verzi metody pro porovnání tří zadaných čísel využijeme volání metody VetsiRovno. Této metodě předáme dvě první čísla (a a b), a návrat ve formě většího čísla porovnáme se třetím číslem c. Pokud je některé ze dvou čísel větší (nebo rovno) než třetí číslo, vypíšeme pouze hodnotu většího čísla z prvních dvou čísel a hodnoty všech zadaných čísel. Pokud neplatí uvedená podmínka, největší číslo je c (třetí zadané číslo) a vypíšeme v dialogovém oknu jeho hodnotu a hodnoty všech zadaných čísel - viz Kód 11. 

// Metoda bez návratu s výpisem maxima a zadaných hodnot - využití metody 'VetsiRovno'
private void BtnPorovnej4_Click(object sender, RoutedEventArgs e)
{
    // Deklarace lokálních proměnných: 'a', 'b', 'c' ... tři celá čísla
    int a, b, c;
 
    // Konverze textu na číslo a uložení do proměnné 'a'
    int.TryParse(TxtA.Text, out a);
    int.TryParse(TxtB.Text, out b);
    int.TryParse(TxtC.Text, out c);
 
    /* Pokud je návrat metody 'VetsiRovno' z prvních dvou porovnávaných čísel větší 
     * (nebo stejné) číslo než 3. číslo potom ... */
    if (VetsiRovno(a, b) >= c)
        // Výpis největší hodnoty z prvních dvou porovnávaných čísel
        MessageBox.Show("Největší (nebo rovné) je " + VetsiRovno(a, b) + " z čisel " + a + ", " + b + ", " + c);
    // Jinak... 
    else
        // Výpis největší hodnoty, tj. 3. čísla
        MessageBox.Show("Největší (nebo rovné) je " + c + " z čísel " + a + ", " + b + ", " + c);
}

Kód 11: Deklarace metody pro porovnání 3 celočíselných hodnot - volání metody s návratem VetsiRovno (BtnPorovnej4_Click)

Poslední volanou metodou, která obsahuje pouze jeden příkaz výpisu v dialogovém oknu je metoda bez návratu BtnPorovnej5_Click. V příkazu je umístěno dvojité volání metody s návratem VetsiRovno. Tímto způsobem nám metoda přímo do výpisu navrátí hodnotu maxima ze všech tří čísel. Pro výpis v dialogovém oknu musíme toto maximum konvertovat na číslice pomocí metody Format, která je vyvolána pomocí tečkové notace datového typu string (tato metoda má různé verze, kterými určíme, v jakém formát má být hodnota vypsána) - viz Kód 12. Jak si můžete všimnout, výpis má stejnou formu, kterou jsme použili při výpisu v konzolové aplikaci.

// Metoda bez návratu s výpisem maxima a zadaných hodnot - dvojité volání metody 'VetsiRovno'
private void BtnPorovnej5_Click(object sender, RoutedEventArgs e)
{
    // Deklarace lokálních proměnných: 'a', 'b', 'c' ... tři celá čísla
    int a, b, c;
 
    // Konverze textu na číslo a uložení do proměnné 'a'
    int.TryParse(TxtA.Text, out a);
    int.TryParse(TxtB.Text, out b);
    int.TryParse(TxtC.Text, out c);
 
    /* Výpis největší hodnoty - využití dvojitého volání metody 'VetsiRovno' - první návrat metody 
     * obsahuje vyšší číslo z prvních dvou předaných čísel -> porovnání návratu metody se třetím 
     * předaným číslem -> získání maxima -> konverze hodnoty na číslice */
    MessageBox.Show(string.Format("Největší (nebo rovné) je {0} z čísel {1}, {2}, {3}", VetsiRovno(VetsiRovno(a, b), c), a, b, c));
}

Kód 12: Deklarace metody pro porovnání 3 celočíselných hodnot - dvojité volání metody VetsiRovno pro návrat maxima (BtnPorovnej5_Click)

Metoda, která zajistí zavření formuláře, je metoda pro obsluhu události Click tlačítka Konec - viz Kód 13.

//Metoda bez návratu pro zavření formuláře
private void BtnKonec_Click(object sender, RoutedEventArgs e)
{
    // Zavření formuláře
    this.Close();
}

Kód 13: Deklarace metody bez návratu pro zavření formuláře (BtnKonec_Click)