Mobiele apps programmeren met Xamarin – De control flow van een C#-programma – Selecties

print

Inhoud


Wat vooraf ging

Deze post sluit aan bij de gelijkaardige post uit Start to program – Control Flow en bij de voorgaande post Mobiele apps programmeren met Xamarin – De control flow van een C#-programma – Invoer en uitvoer.

Een groot deel van deze post zal een kopie-paste zijn uit Start to program – Control Flow maar dan aangepast aan C# en met voorbeelden in Xamarin.


Beslissingen nemen

In het dagelijks leven doen we het constant, beslissingen nemen. Als een bepaalde conditie vervult is dananders…. Als het regent dan nemen we de auto anders gaan we per fiets.

In een computerprogramma is het niet anders. Ook hier zullen heel vaak beslissingen genomen dienen te worden. De beslissingen worden genomen naargelang de uitkomst van een vergelijking (een conditie) waar is of onwaar is. Is deze vergelijking waar, dan gaat het programma de Waar-kant uit, anders, de vergelijking is onwaar, dan gaat het de Onwaar-kant uit.

Beslissingen worden genomen door middel van programmeercode gebruikmakend van Conditional Statements.


Merk de symboliek op:

  • Een ovaal voor Starten en Stoppen van het programma/script.
  • Een parallellogram voor invoer en uitvoer.
  • Een rechthoek voor een proces, verwerking/bewerking.
  • Een ruit start een beslissing.
  • Een beslissing heeft een Ja-kant (waar) en een Nee-kant (onwaar).

Boolean expressie

Een boolean expressie is een expressie (een stelling) die enkel de uitkomst waar (true) of onwaar (false) kan hebben.

Bijvoorbeeld:

3 < 2

Dit is een boolean expressie want het antwoord is onwaar.

De conditie/vergelijking

De beslissing bestaat uit een conditie/vergelijking en is ene booleaanse expressie. De uitkomst van de vergelijking is dus ofwel Waar (true) ofwel Onwaar (false).

Een conditie kan ook uit meerdere vergelijkingen bestaan. Meerdere vergelijkingen worden aan mekaar verbonden door logische operatoren.

Vergelijkingsoperatoren

Onderstaande tabel toont de vergelijkingsoperatoren van C# (en de misschien reeds gekende uit Javascript).

BetekenisC#Javascript
Is gelijk aan"==""=="
Is niet gelijk aan!=!=
Is kleiner dan<<
Is groter dan>>
Is kleiner dan of gelijk aan<=<=
Is groter dan of gelijk aan>=>=
Is gelijk aan en van hetzelfde type"==="
Is niet gelijk aan of niet van hetzelfde type!==

Opmerking: de “” rond “==” en “===” staan er enkel om een foutmelding van WordPress te omzeilen, zij moeten in uw programmeercode worden weggelaten!

Voorbeelden

VergelijkingJavascriptC#
2<12truetrue
7<=12truetrue
5==8falsefalse
5=="5"trueNiet mogelijk in C#
5===5trueNiet mogelijk in C#
5==="5"falseNiet mogelijk in C#
5!=5falsefalse
5!=8truetrue
2<"12"trueNiet mogelijk in C#
2<"A12"falseNiet mogelijk in C#
2<"Jan"falseNiet mogelijk in C#
0==""trueNiet mogelijk in C#
0 == " " (spatie)trueNiet mogelijk in C#
1 == " " (spatie)falseNiet mogelijk in C#
"A" < "B"trueNiet mogelijk in C#
"Aa" < "B"trueNiet mogelijk in C#
"BA" < "B"falseNiet mogelijk in C#

Conditional Statements (if-statement)

Conditional statements worden gebruikt om acties uit te voeren op basis van het al dan niet waar zijn van een bepaalde conditie.

C# kent de volgende conditional statements:

  • Gebruik if om een Block statement uit te voeren indien een bepaalde conditie waar is.
  • Gebruik else om een Block statement uit te voeren indien een bepaalde conditie onwaar is.
  • Gebruik else if om een nieuwe conditie te testen indien de vorige conditie onwaar was.
  • Gebruik switch om verschillende alternatieve blokken aan te bieden naargelang de waarde van een conditie (variabele). Dit is een speciale schrijfwijze van het if-statement dat nogal programmeertaal gebonden is en dat ik hier niet ga behandelen.

if-statement

Gebruik if() om een Block statement uit te voeren indien een bepaalde conditie waar is.

if(conditie){
Statements indien waar;
}

else-statement

Gebruik else om een Block statement uit te voeren indien een bepaalde conditie onwaar is. Het else-statement kan niet zonder het if-statement!

if(conditie){
Statements indien waar;
}
else{
Statements indien onwaar;
}

else if-statement

Gebruik else if() om een nieuwe conditie te testen indien de vorige conditie onwaar was.

Of anders gezegd, soms hebt u geen 2 opties (bv. positief of negatief) maar hebt u meer dan 2 opties (bv. positief, negatief of nul). Dit betekent dat er meerdere condities (en dus ook if’en) zullen zijn (bv. eerst nagaan of het getal positief is, indien het niet positief is nagaan of het nul is en indien het niet positief of nul is zal het negatief zijn).

Strikt genomen kan je stellen dat er steeds 1 conditie (if) minder is dan het aantal opties.

if(conditie 1){
Statements indien conditie 1 waar;
} else if(conditie 2){
Statements indien conditie 1 onwaar is maar conditie 2 wel waar is;
}
else{
Statements indien conditie 1 onwaar is en conditie 2 ook onwaar is;
}

Neem eens een kijkje in de officiële documentatie voor meer voorbeelden en uitleg.

Voor ik over ga naar een paar voorbeelden eerst even stil staan bij logische operatoren!

Logische operatoren

BetekenisOperator
NOT!
AND (en)&&
OR (of)||
XOR^

De uitkomst van vergelijkingen met logische operatoren

Vergelijking 1Vergelijking 21 AND 2 (1 && 2)1 OR 2 (1 || 2)NOT 1 (!1)1 XOR 2 (1 ^ 2)
truetruetruetruefalsefalse
truefalsefalsetruefalsetrue
falsetruefalsetruetruetrue
falsefalsefalsefalsetruefalse

Of anders gezegd:

  • Vergelijkingen combineren met AND-operator is enkel true als alle vergelijkingen true zijn.
  • Vergelijkingen combineren met OR-operator is true van zodra er één vergelijking true is.

Je zou dus kunnen stellen dat de AND-operator strikter/strenger is dan de OR-operator, je krijgt minder snel een true.

Weet ook dat alles wat u combineert met de AND-operator ook kan gecombineerd worden met de OR-operator. U moet dan wel de condities omkeren!

Bijvoorbeeld, een Getal moet liggen tussen 0 en 20. U kunt nu de conditie opbouwen met de AND-operator:

Getal >= 0 && Getal <= 20;

Dezelfde conditie met de OR-operator wordt nu:

Getal < 0 || Getal > 20

De true-kant en de false-kant worden nadien ook omgedraaid!

Merk ook op dat u de condities moet volledig typen. Het onderstaande is dus FOUT:

getal < 0 || > 20

Voorbeelden

VergelijkingResultaat
5 < 10 && 3 > 1true
5 < 10 && 1 > 3false
5 < 10 || 1 > 3true
true && (3 == 4)false
false || (3 == 4)false
Een variabele Getal moet groter zijn dan 0Getal > 0
Een variabele Getal moet groter dan of gelijk zijn aan 0Getal >= 0
Een variabele Tekst mag niet leeg zijn Tekst != “”
Een variabele Getal moet liggen tussen 0 en 20(Getal >= 0) && (Getal <= 20)
Een variabele Teken moet gelijk zijn aan “a” of “c”(Teken == “a”) || (Teken == “c”)

Bitwise operatoren

Naast de Logische operatoren bestaan er ook nog zogenaamde Bitwise operatoren. Aangezien we deze niet meteen in praktijk gaan gebruiken verwijs ik u graag voor meer informatie door naar de Officiële documentatie.

Voorbeeld 1: positief, negatief of nul?

De gebruiker moet een getal invoeren.

Na het klikken op een knop/button moet worden weergegeven of het getal positief was. Is het niet positief dan wordt niets getoond.

Het scherm kan er als volgt uitzien. De cursor staat in het tekstvak waardoor het numerieke toetsenbord te zien is.

XAML

De XAML om deze pagina vindt u hieronder.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Control_Flow.Pos_Neg_Nul">
    <StackLayout Margin="10">
        <Label Text="Positief, negatief of nul?" FontSize="Large" HorizontalTextAlignment="Center"></Label>
        <Entry x:Name="entryInvoer" Placeholder="Getal" Keyboard="Numeric" ></Entry>
        <Button Text="Berekenen" Clicked="Button_Clicked"></Button>
        <Label x:Name="lblUitvoer" HorizontalOptions="FillAndExpand" BackgroundColor="Red" TextColor="Yellow" HeightRequest="30" VerticalTextAlignment="Center" ></Label>
    </StackLayout>
</ContentPage>

Deze XAML zou geen geheimen meer mogen bevatten. Kijk wel even naar de gebruikte namen.

Code-behind

Versie 1 – if-statement

De programmeercode ziet er als volgt uit.

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Control_Flow
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Pos_Neg_Nul : ContentPage
    {
        public Pos_Neg_Nul()
        {
            InitializeComponent();
        }

        private void Button_Clicked(object sender, EventArgs e)
        {
            //invoer
            Int16 getal = Convert.ToInt16(entryInvoer.Text);

            //bewerking en uitvoer
            if (getal >= 0)
            {
                lblUitvoer.Text = "Het getal is positief.";
            }
        }
    }
}

Het te bewerken getal wordt opgevraagd, geconverteerd en toegekend aan een variabele.

Int16 getal = Convert.ToInt16(entryInvoer.Text);

Controleer of het getal groter dan of gelijk is aan 0.

if(getal >= 0)

Als dit waar is (het getal is groter) geef dan een gepaste uitvoer.

lblUitvoer.Text = "Het getal is positief.";

Versie 2 – else statement
Indien het getal niet positief is moet gemeld worden dat het negatief is.

De code wordt nu:

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Control_Flow
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Pos_Neg_Nul : ContentPage
    {
        public Pos_Neg_Nul()
        {
            InitializeComponent();
        }

        private void Button_Clicked(object sender, EventArgs e)
        {
            //invoer
            Int16 getal = Convert.ToInt16(entryInvoer.Text);

            //bewerking en uitvoer
            if (getal >= 0)
            {
                lblUitvoer.Text = "Het getal is positief.";
            }
            else
            {
                lblUitvoer.Text = "Het getal is negatief.";
            }
        }
    }
}
Versie 3 – else if-statement
Eigenlijk is nul strikt genomen niet echt positief. Er moet dus een derde melding komen als het getal gelijk is aan nul.

Hiervoor dient een bijkomende if toegevoegd. 3 opties betekent immers 2 keer if. Dit gebeurt via een else if-statement.

De code wordt nu:

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Control_Flow
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Pos_Neg_Nul : ContentPage
    {
        public Pos_Neg_Nul()
        {
            InitializeComponent();
        }

        private void Button_Clicked(object sender, EventArgs e)
        {
            //invoer
            Int16 getal = Convert.ToInt16(entryInvoer.Text);

            //bewerking en uitvoer
            if (getal > 0)
            {
                lblUitvoer.Text = "Het getal is positief.";
            }
            else if (getal < 0)
            {
                lblUitvoer.Text = "Het getal is negatief.";
            }
            else
            {
                lblUitvoer.Text = "Het getal is nul.";
            }
        }
    }
}

Merk op dat er ook andere benaderingen mogelijk zijn die even goed zijn (bv. eerst testen op het 0 zijn).

Foutopvang

Try{…} Catch{…}

U kunt ook de fouten opvangen met een try{} catch{} die we reeds besproken hebben.

Heel de code, hoewel dit in principe te veel is van het goede, komt in de try{}. Een passende foutmelding komt in de catch{}. De fout wordt weergegeven in een boodschappenvenster. Vergeet niet uw functie asynchroon te maken.

De finale code wordt dan:

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Control_Flow
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Pos_Neg_Nul : ContentPage
    {
        public Pos_Neg_Nul()
        {
            InitializeComponent();
        }

        private async void Button_Clicked(object sender, EventArgs e)
        {
            try
            {
                //invoer
                Int16 getal = Convert.ToInt16(entryInvoer.Text);

                //bewerking en uitvoer
                if (getal > 0)
                {
                    lblUitvoer.Text = "Het getal is positief.";
                }
                else if (getal < 0)
                {
                    lblUitvoer.Text = "Het getal is negatief.";
                }
                else
                {
                    lblUitvoer.Text = "Het getal is nul.";
                }
            }
            catch
            {
                //uitvoer
                await DisplayAlert("Foutieve invoer", "U hebt geen correct getal ingevoerd!", "OK");
            }
        }
    }
}
TryParse

U kunt ook de C#-methode TryParse gebruiken. TryParse zal proberen de invoer te converteren naar het gewenste type. Lukt dat, dan hebt u een true, anders een false.

Definieer eerst de variabele en het gewenste type.

Int16 getal;

Vervolgens probeert u de TryParse met de gewenste variabele als output. Dit zal lukken en levert een true op of zal mislukken en levert een false op. Dit resultaat wordt toegekend aan een variabele van het type bool.

bool Resultaat = Int16.TryParse(entryInvoer.Text, out getal);

Als dit resultaat true is dan wordt de “normale” code verder gezet.

if(Resultaat == true)

of kortweg:

if(Resultaat)

In het else-gedeelte komt dan de foutmelding.

else
{
//uitvoer
await DisplayAlert("Foutieve invoer", "U hebt geen correct getal ingevoerd!", "OK");
}

De finale code wordt dan:

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Control_Flow
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Pos_Neg_Nul : ContentPage
    {
        public Pos_Neg_Nul()
        {
            InitializeComponent();
        }

        private async void Button_Clicked(object sender, EventArgs e)
        {

            //invoer
            Int16 getal;
            bool Resultaat = Int16.TryParse(entryInvoer.Text, out getal);

            if(Resultaat)
            {
                //bewerking en uitvoer
                if (getal > 0)
                {
                    lblUitvoer.Text = "Het getal is positief.";
                }
                else if (getal < 0)
                {
                    lblUitvoer.Text = "Het getal is negatief.";
                }
                else
                {
                    lblUitvoer.Text = "Het getal is nul.";
                }
            }
            else
            {
                //uitvoer
                await DisplayAlert("Foutieve invoer", "U hebt geen correct getal ingevoerd!", "OK");
            }

        }
    }
}

Voorbeeld 2: geslaagd of niet geslaagd?

Om geslaagd te zijn moeten aan 3 condities voldaan zijn:

  • De cursist moet minimaal 50 % halen,
  • de cursist mag niet meer dan 1 tekort hebben,
  • de cursist mag niet meer dan 2 keer onwettig afwezig zijn.

Invoer

Het aantal tekorten en het aantal keer onwettig afwezig worden ingevoerd. Gebruik hiervoor 2 tekstvakken.

Het percentage wordt willekeurig door de computer berekend.

Verwerking en uitvoer

Bij een klik op een Button wordt het, door de computer berekend, percentage in een Label weergegeven. In een tweede Label komt of de cursist “Geslaagd” is of “Niet geslaagd”. Plaats ook een gepaste titel bovenaan de app.

Het scherm kan er ongeveer als volgt uitzien.

XAML

De XAML zou opnieuw moeten duidelijk zijn.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Control_Flow.Geslaagd">
    <StackLayout Margin="10">
        <Label Text="Geslaagd?" FontSize="Large" HorizontalTextAlignment="Center"></Label>
        <StackLayout Orientation="Horizontal">
            <Label Text="Aantal tekorten:" HeightRequest="40" WidthRequest="150" VerticalTextAlignment="Center"></Label>
            <Entry x:Name="entryTekorten" Placeholder="Tekorten" HorizontalOptions="FillAndExpand" Keyboard="Numeric" ></Entry>
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Aantal keer afwezig:" HeightRequest="40" WidthRequest="150" VerticalTextAlignment="Center"></Label>
            <Entry x:Name="entryAfwezig" Placeholder="Afwezig" HorizontalOptions="FillAndExpand" Keyboard="Numeric" ></Entry>
        </StackLayout>
        <Button Text="Berekenen" Clicked="Button_Clicked"></Button>
        <Label x:Name="lblPercentage" Text="Hier komt het behaalde percentage." HeightRequest="30" ></Label>
        <Label x:Name="lblResultaat" Text="Hier komt het behaalde resultaat." BackgroundColor="Red" TextColor="Yellow" HeightRequest="30" VerticalTextAlignment="Center" ></Label>
    </StackLayout>
</ContentPage>

Code-behind

Deze oefening bevat 2 problemen die wat extra aandacht verdienen.

De berekening van het willekeurige getal.

In een vorige post hebt u reeds gezien hoe u een willekeurig getal kunt genereren. Ik verwijs naar deze post voor de uitleg en beperk me hier tot de uiteindelijke formule.

Random Willekeurig = new Random();
int Percentage = Willekeurig.Next(0, 101);

De drievoudige conditie.

De cursist is pas geslaagd als hij:

  • minimaal 50 % haalt,
  • niet meer dan 1 tekort heeft,
  • niet meer dan 2 keer onwettig afwezig was.

Dit vertaalt zich in onderstaande samengestelde condite:

(Percentage >= 50) && (AantalTekorten <= 1) && (AantalAfwezigheden <= 2)

De rest van de programmeercode zou moeten duidelijk zijn.

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Control_Flow
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Geslaagd : ContentPage
    {
        public Geslaagd()
        {
            InitializeComponent();
        }

        private void Button_Clicked(object sender, EventArgs e)
        {
            //invoer    
            Random Willekeurig = new Random();
            int Percentage = Willekeurig.Next(0, 101);

            Int16 AantalTekorten = Convert.ToInt16(entryTekorten.Text);
            Int16 AantalAfwezigheden = Convert.ToInt16(entryAfwezig.Text);
            string Resultaat = "";

            //Bewerkingen
            if ((Percentage >= 50) && (AantalTekorten <= 1) && (AantalAfwezigheden <= 2))
            {
                Resultaat = "De cursist is geslaagd.";
            }
            else
            {
                Resultaat = "De cursist is niet geslaagd.";
            }

            //Uitvoer
            lblPercentage.Text = string.Format("Het behaalde percentage is {0:p2}.", (decimal)Percentage / 100);
            lblResultaat.Text = Resultaat;
        }
    }
}

Merk ook op hoe de uitvoer geformatteerd is om het als een percentage met 2 cijfers na de komma weer te geven. Om dit correct te laten werken moet het percentage ook geconverteerd worden naar een decimaal type en gedeeld door 100.

lblPercentage.Text = string.Format("Het behaalde percentage is {0:p2}.", (decimal)Percentage / 100);

Versie 2 – meerdere opties

Voeg aan bovenstaande voorbeeld onderstaande opties toe:

  • Indien de cursist geslaagd is met een % tussen de 50% (inbegrepen) en de 70% dan is hij “Geslaagd met voldoening”.
  • Indien de cursist geslaagd is met een % tussen de 70% (inbegrepen) en de 90% dan is hij “Geslaagd met onderscheiding”.
  • Indien hij geslaagd is met een % van 90% of meer dan is hij “Geslaagd met grote onderscheiding”.

De code wordt nu:

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Control_Flow
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Geslaagd : ContentPage
    {
        public Geslaagd()
        {
            InitializeComponent();
        }

        private void Button_Clicked(object sender, EventArgs e)
        {
            //invoer    
            Random Willekeurig = new Random();
            int Percentage = Willekeurig.Next(0, 101);

            Int16 AantalTekorten = Convert.ToInt16(entryTekorten.Text);
            Int16 AantalAfwezigheden = Convert.ToInt16(entryAfwezig.Text);
            string Resultaat = "";

            //Bewerkingen
            if ((Percentage < 50) || (AantalTekorten > 1) || (AantalAfwezigheden > 2))
            {
                Resultaat = "De cursist is niet geslaagd.";
            }
            else if (Percentage < 70)
            {
                Resultaat = "De cursist is geslaagd met voldoening.";
            }
            else if (Percentage < 90)
            {
                Resultaat = "De cursist is geslaagd met onderscheiding.";
            }
            else
            {
                Resultaat = "De cursist is geslaagd met grote onderscheiding.";
            }

            //Uitvoer
            lblPercentage.Text = string.Format("Het behaalde percentage is {0:p2}.", (decimal)Percentage / 100);
            lblResultaat.Text = Resultaat;
        }
    }
}

Foutopvang

Ik ga nu nog de nodige foutopvang toevoegen gebruikmakend van TryParse.

Er moeten 2 invoeren gecontroleerd worden dus zal er ook 2 keer een TryParse getest worden die beiden true moeten zijn.

Int16 AantalTekorten;
Int16 AantalAfwezigheden;
bool Test1 = Int16.TryParse(entryTekorten.Text, out AantalTekorten);
bool Test2 = Int16.TryParse(entryAfwezig.Text, out AantalAfwezigheden);
if(Test1 && Test2){
...
}

De finale code is nu:

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Control_Flow
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Geslaagd : ContentPage
    {
        public Geslaagd()
        {
            InitializeComponent();
        }

        private async void Button_Clicked(object sender, EventArgs e)
        {
            //invoer    
            Random Willekeurig = new Random();
            int Percentage = Willekeurig.Next(0, 101);
            string Resultaat = "";

            Int16 AantalTekorten;
            Int16 AantalAfwezigheden;

            bool Test1 = Int16.TryParse(entryTekorten.Text, out AantalTekorten);
            bool Test2 = Int16.TryParse(entryAfwezig.Text, out AantalAfwezigheden);

            if(Test1 && Test2)
            {
                //Bewerkingen
                if ((Percentage < 50) || (AantalTekorten > 1) || (AantalAfwezigheden > 2))
                {
                    Resultaat = "De cursist is niet geslaagd.";
                }
                else if (Percentage < 70)
                {
                    Resultaat = "De cursist is geslaagd met voldoening.";
                }
                else if (Percentage < 90)
                {
                    Resultaat = "De cursist is geslaagd met onderscheiding.";
                }
                else
                {
                    Resultaat = "De cursist is geslaagd met grote onderscheiding.";
                }


                //Uitvoer
                lblPercentage.Text = string.Format("Het behaalde percentage is {0:p2}.", (decimal)Percentage / 100);
                lblResultaat.Text = Resultaat;
            }
            else
            {
                //uitvoer
                await DisplayAlert("Foutieve invoer", "U hebt geen correct getal ingevoerd!", "OK");
            }

        }
    }
}

Voorbeeld 3: Kleuren selecteren

Bouw onderstaande pagina die 3 Sliders bevat met een waarde tussen 0 en 255. Deze Sliders worden gebruikt om de kleur van een BoxView te bepalen.

XAML

Hieronder vindt u de XAML. Hij bevat Sliders, Labels en een BoxView. Merk op dat alle Sliders dezelfde event ValueChanged="OnSliderValueChanged" aanroepen. Verder zijn er geen bijzonderheden aan deze XAML.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Control_Flow.KleurenSelecteren">
    <StackLayout Margin="10">
        <Label Text="Kleuren selecteren" FontSize="Large" HorizontalTextAlignment="Center"></Label>
        <Slider x:Name="redSlider" ValueChanged="OnSliderValueChanged" Maximum="255" />
        <Label x:Name="redLabel" HorizontalTextAlignment="Center" Text="Rood"/>
        <Slider x:Name="greenSlider" ValueChanged="OnSliderValueChanged" Maximum="255" />
        <Label x:Name="greenLabel" HorizontalTextAlignment="Center" Text="Groen"/>
        <Slider x:Name="blueSlider" ValueChanged="OnSliderValueChanged" Maximum="255" />
        <Label x:Name="blueLabel" HorizontalTextAlignment="Center" Text="Blauw"/>
        <BoxView x:Name="boxView" VerticalOptions="FillAndExpand" />
    </StackLayout>
</ContentPage>

Code-behind

Bekijk de onderstaande code-behind, de uitleg volgt eronder.

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Control_Flow
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class KleurenSelecteren : ContentPage
    {
        public KleurenSelecteren()
        {
            InitializeComponent();

            redSlider.Value = 128;
            greenSlider.Value = 128;
            blueSlider.Value = 128;

        }

        private void OnSliderValueChanged(object sender, ValueChangedEventArgs e)
        {
            if (sender == redSlider)
            {
                redLabel.Text = String.Format("Rood = {0}", (int)redSlider.Value);
            }
            else if (sender == greenSlider)
            {
                greenLabel.Text = String.Format("Groen = {0}", (int)greenSlider.Value);
            }
            else 
            {
                blueLabel.Text = String.Format("Blauw = {0}", (int)blueSlider.Value);
            }

            boxView.Color = Color.FromRgb((int)redSlider.Value, (int)greenSlider.Value, (int)blueSlider.Value);

        }
    }
}

Bij het initialiseren, opstarten, van de pagina worden de sliders op hun middelste waarde geplaatst.

redSlider.Value = 128;
greenSlider.Value = 128;
blueSlider.Value = 128;

De event maakt gebruik van de sender om te bepalen welke slider er verschoven is. U weet dat alle sliders dezelfde event aanroepen. De sender is dus de slider die momenteel van waarde verandert.


if (sender == redSlider){...}
else if (sender == greenSlider){...}
else {...}

Onderstaande code verzorgt de uitvoer.

redLabel.Text = String.Format("Rood = {0}", (int)redSlider.Value);

Omdat de Value van een slider van het type double is worden ze geconverteerd naar het type int zodat enkel de gehele waarde wordt getoond.

De methode Color.FromRgb wordt gebruikt om de kleuren aan de BoxView toe te kennen. Color.FromRgb heeft 3 parameter voor respectievelijk rood, groen en blauw.

boxView.Color = Color.FromRgb((int)redSlider.Value, (int)greenSlider.Value, (int)blueSlider.Value);


Conditional Statements (switch-statement)

Een switch voegt geen bijkomende mogelijkheden toe, het is gewoon een alternatieve syntax voor bepaalde if-statements wanneer deze te complex dreigen te worden.

De syntax van een switch is:

switch(expressie) {
case waarde-expressie :
statement(s);
break;
case waarde-expressie :
statement(s);
break;
...
default : /* Optioneel */
statement(s);
break;
}

Belangrijk, vergeet de break; niet!

Bekijk het onderstaande console-programma als illustratie.

using System;
					
public class Program
{
	public static void Main()
	{
      int caseSwitch = 1;
      
      switch (caseSwitch)
      {
          case 1:
              Console.WriteLine("Case 1");
              break;
          case 2:
              Console.WriteLine("Case 2");
              break;
          default:
              Console.WriteLine("Default case");
              break;
      }
	}
}

Hieronder wordt een switch gebruikt om te kijken of het al weekend is.

using System;
					
public class Program
{
	public static void Main()
	{
        switch (DateTime.Now.DayOfWeek)
        {
           case DayOfWeek.Sunday:
           case DayOfWeek.Saturday:
              Console.WriteLine("Eindelijk... weekend!");
              break;
           case DayOfWeek.Monday:
              Console.WriteLine("We zijn eraan begonnen! Nog een lange weg te gaan, maar we houden de moed er in.");
              break;
           case DayOfWeek.Friday:
              Console.WriteLine("We zijn er bijna, we zijn er bijna...");
              break;
           default:
              Console.WriteLine("Pff, nog zo lang.");
			  break;
        }
	}
}

Actielijst

Bij het klikken op een knop moet een lijst met mogelijke acties verschijnen. Het programma moet achterhalen welke actie aangeklikt is.

XAML

De XAML in het bestand MainPage.xaml bevat gewoon een Label en een Button, binnen een StackLayout. Aan de Button is een Clicked-event toegevoegd.

  • Wijzig de XAML in:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:Actielijst" x:Class="Actielijst.MainPage">
    <StackLayout>
	    <Label Text="Welcome to Xamarin Forms!" VerticalOptions="Center" HorizontalOptions="Center" FontSize="Large"/>
        <Button Text="Beheer" Clicked="Button_Clicked"></Button>
        
    </StackLayout>

</ContentPage>

Code-behind

De code-behind in MainPage.xaml.cs moet de actielijst weergeven. Dit gebeurt gebruikmakend van DisplayActionSheet. De syntax is:

public System.Threading.Tasks.Task DisplayActionSheet (String title, String cancel, String destruction, params String[] buttons)

Er wordt een taak van het type string teruggegeven. U weet dat u een taak het best asynchroon behandelt.

Er worden 4 parameters verwacht allen van het type string, respectievelijk:

  • De Titel
  • De Cancel-knop
  • De Destruction-knop
  • Een lijst van andere knoppen params String[] buttons

De code die gebruikt wordt in bovenstaande schermafdruk is:

String actie = await DisplayActionSheet("Wat wilt u doen?", "Annuleren", "Verwijderen", "Zoeken", "Wijzigen", "Toevoegen");

Hoe deze actielijst wordt weergegeven wordt bepaalt door de device zelf. Persoonlijk vindt ik plaatsing van de destruction-knop op een Android (zie bovenstaande schermafdruk) nogal ongelukkig, hij neemt eerder de plaats in van een OK-knop en zou misschien ook als zodanig kunnen gebruikt worden.

Om na te gaan welke actie gekozen is kan de waarde van de variabele actie gecontroleerd worden met een switch. Er wordt telkens een boodschap, DisplayAlert getoond die aangeeft op welke knop er geklikt is.

switch(actie)
{
case "Verwijderen":
await DisplayAlert("Beheer", "U wilt verwijderen.", "OK");
break;
case "Zoeken":
await DisplayAlert("Beheer", "U wilt zoeken.", "OK");
break;
case "Wijzigen":
await DisplayAlert("Beheer", "U wilt wijzigen.", "OK");
break;
case "Toevoegen":
await DisplayAlert("Beheer", "U wilt toevoegen.", "OK");
break;
}

De volledige code-behind is nu:

using System;
using Xamarin.Forms;

namespace Actielijst
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private async void Button_Clicked(object sender, EventArgs e)
        {
            String actie = await DisplayActionSheet("Wat wilt u doen?", "Annuleren", "Verwijderen", "Zoeken", "Wijzigen", "Toevoegen");

            switch(actie)
            {
                case "Verwijderen":
                    await DisplayAlert("Beheer", "U wilt verwijderen.", "OK");
                    break;
                case "Zoeken":
                    await DisplayAlert("Beheer", "U wilt zoeken.", "OK");
                    break;
                case "Wijzigen":
                    await DisplayAlert("Beheer", "U wilt wijzigen.", "OK");
                    break;
                case "Toevoegen":
                    await DisplayAlert("Beheer", "U wilt toevoegen.", "OK");
                    break;
            }

        }
    }
}

Wilt u een bepaalde knop niet, bv. u wenst geen Destruction-knop, dan zet u op de plaats waar normaal de tekst van die knop komt de waarde null.

Bijvoorbeeld:

String actie = await DisplayActionSheet("Wat wilt u doen?", "Annuleren", null, "Zoeken", "Wijzigen", "Toevoegen");


Design guides

Onderstaande design guides sluiten aan bij wat besproken is in deze post. Ik raad aan deze zeker eens te bekijken.

Android

iOS

UWP


Behandelde Basiscompetenties uit de module ICT Programmeren – Specifieke ontwikkelomgeving: eenvoudige functionaliteiten

  • IC BC017 – kan ICT veilig en duurzaam gebruiken
  • IC BC234 – kan de basisprincipes van programmeren in een specifieke ontwikkelomgeving toepassen
  • IC BC236 – kan eenvoudige wijzigingen aan een programma aanbrengen
  • IC BC241 – kan een programma in een specifieke ontwikkelomgeving maken
  • IC BC250 – kan bij het programmeren in functie van een specifieke ontwikkelomgeving, een juiste logica volgen

Geef een reactie

Deze website gebruikt Akismet om spam te verminderen. Bekijk hoe je reactie-gegevens worden verwerkt.

  • Abonneer je op deze website d.m.v. e-mail

    Voer je e-mailadres in om je in te schrijven op deze website en e-mailmeldingen te ontvangen van nieuwe berichten.