De anatomie van een C#-programma – Collections

print

Inhoud


Wat vooraf ging

Klassen toevoegen

  • Voeg een Klasse Persoon toe via rechtsklik op het algemene (Portable) project – AddNew item….

  • Kies voor Class en geef het de naam Persoon.

  • Voeg de onderstaande code toe aan de klasse Persoon. De bespreking van de klasse vindt u in deze post.
using System;

namespace Lijsten
{
    public class Persoon
    {
        public string Achternaam { get; set; }
        public string Voornaam { get; set; }
        private DateTime _GeboorteDatum;

        public DateTime Geboortedatum
        {
            get { return _GeboorteDatum; }
            set
            {
                if (DateTime.Compare(value, DateTime.Today) != 1)
                {
                    _GeboorteDatum = value;
                }
                else
                {
                    throw new Exception("De geboortedatum mag niet in de toekomst liggen!");
                }
            }
        }


        public Persoon()
        {
            Achternaam = "";
            Voornaam = "";
            Geboortedatum = DateTime.Today;
        }

        public Persoon(string Achter, string Voor, DateTime Datum)
        {
            Achternaam = Achter;
            Voornaam = Voor;
            Geboortedatum = Datum;
        }

        public override string ToString()
        {
            return Voornaam + " " + Achternaam + " - " + Geboortedatum.ToString("d");
        }

        public string Naam()
        {
            return Achternaam + " " + Voornaam;
        }
    }
}

Er zijn twee kleine wijzigingen tenopzichte van dezelfde code in de vorige post over klassen.

De klasse is public gemaakt public class Persoon.

De weergave van de geboortedatum is gewijzigd in Geboortedatum.ToString("d").

  • Voeg nu, analoog met hierboven, de klasse Cursist toe (ook van deze klasse vindt u de nodige uitleg in deze post).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lijsten
{
    public class Cursist: Persoon
    {
        private int _Cursistnummer;
        public int Cursistnummer
        {
            get { return _Cursistnummer; }
            set
            {
                if (value >= 0)
                {
                    _Cursistnummer = value;
                }
                else
                {
                    throw new Exception("Geef een positieve waarde in voor het cursistnummer!");
                }
            }
        }

        public Cursist()
        {
            Cursistnummer = 0;

        }

        public Cursist(int Nummer, string Achter, string Voor, DateTime Datum)
        {
            Cursistnummer = Nummer;
            Achternaam = Achter;
            Voornaam = Voor;
            Geboortedatum = Datum;
        }

        public override string ToString()
        {
            return Cursistnummer + ": " + Voornaam + " " + Achternaam + " - " + Geboortedatum.ToString("d");
        }
    }
}

Ook deze klasse is public gemaakt public class Cursist: Persoon.

De weergave van de geboortedatum is eveneens gewijzigd in Geboortedatum.ToString("d").

De XAML lay-out

  • Wijzig de XAML van MainPage.xaml in onderstaande code.
<?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:Lijsten;assembly=Lijsten" x:Class="Lijsten.MainPage">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <ListView x:Name="CursistenLijst" ></ListView>

        <ScrollView x:Name="Buttons" Grid.Column="1">
            <StackLayout >
                <Entry x:Name="TxtZoeken" Placeholder="Zoeken"></Entry>
                <Button Text="Toevoegen" x:Name="BtnToevoegen" Clicked="BtnToevoegen_Clicked"/>
                <Button Text="Item Verwijderen" x:Name="BtnVerwijderen" Clicked="BtnVerwijderen_Clicked" />
                <Button Text="Opzoeken" x:Name="BtnOpzoeken" Clicked="BtnOpzoeken_Clicked" />
                <Button Text="Sorteer op naam" x:Name="BtnSorteer" Clicked="BtnSorteer_Clicked" />
                <Button Text="Info" x:Name="BtnInfo" Clicked="BtnInfo_Clicked"/>
                <Button Text="Leeg maken" x:Name="BtnLeeg" Clicked="BtnLeeg_Clicked" />
            </StackLayout>
        </ScrollView>
        
        <ContentView x:Name="overlay" IsVisible="False" BackgroundColor="#C0808080" Padding="10, 0" Grid.Column="0">
            <StackLayout BackgroundColor="White" HorizontalOptions="Center" VerticalOptions="Start" Margin="0,20,0,0" >

                <Label BackgroundColor="Black" FontSize="18" TextColor="White" HorizontalOptions="Fill" Text="Cursist toevoegen" />

                <Entry x:Name="Cursistnr" Placeholder="Cursistnr" HorizontalOptions="FillAndExpand" Keyboard="Numeric"/>
                <Entry x:Name="CursistNaam" Placeholder="Naam van de cursist" HorizontalOptions="FillAndExpand"/>
                <Entry x:Name="CursistVoornaam" Placeholder="Voornaam van de cursist" HorizontalOptions="FillAndExpand"/>
                <DatePicker x:Name="CursistGeboortedatum" HorizontalOptions="FillAndExpand" />
                <StackLayout Orientation="Horizontal" HorizontalOptions="Center">
                    <Button x:Name="BtnAnnuleren" Text="Annuleren" VerticalOptions="CenterAndExpand" HorizontalOptions="Center" Clicked="BtnAnnuleren_Clicked"/>
                    <Button x:Name="BtnOk" Text="OK" VerticalOptions="CenterAndExpand" HorizontalOptions="Center" Clicked="BtnOk_Clicked"/>
                </StackLayout>

            </StackLayout>
        </ContentView>
    </Grid>

</ContentPage>

Er wordt een Grid met twee gelijke kolommen gemaakt.

In de eerste kolom wordt een ListView geplaatst. In de rechterkolom komen een aantal Buttons.

Tevens wordt een ContentView aangemaakt die eveneens in de eerste kolom komt maar slechts zichtbaar zal zijn indien er een cursist wordt toegevoegd.

Onderstaande afbeelding toont het programma bij het toevoegen van een cursist.


Collections

Collections zijn net als Arrays lijsten van gerelateerde informatie. Collections zijn echter flexibelere en zijn te verkiezen indien u een lijst van objecten wenst bij te houden gebaseerd op een, al dan niet zelf gemaakte, klasse.

C# kent verschillende Collections o.a:

  • List<T> – Een lijst van objecten toegankelijk via een index.
  • Dictionary<TKey,TValue> – Een collectie van key/value paren georganiseerd op basis van de key.
  • SortedList<TKey,TValue> – Een gesorteerde collectie van key/value paren georganiseerd op basis van de key.
  • Queue – Een collectie van objecten op basis van FIFO (first in first out).
  • Stack – Een collectie van objecten op basis van LIFO (last in first out).

Deze collecties kunnen generic zijn. Dit wil zeggen dat alle objecten van eenzelfde type zijn.

In deze post ga ik dieper in op het gebruik van de generieke List<T>.


Een generieke lijst

We gaan dit voorbeeld verder uitwerken op basis van een generieke lijst van cursisten.

Declaratie

De generieke lijst van cursisten (objecten van de klasse Cursist) wordt als volgt gedeclareerd:

List<Cursist> Cursisten = new List<Cursist>();

Cursisten toevoegen aan de lijst

Onderstaande code toont hoe u cursisten kunt toevoegen aan de lijst gebruikmakend van de constructor public Cursist(int Nummer, string Achter, string Voor, DateTime Datum).

Cursisten.Add(new Cursist(1, "Linthoudt", "Geert", new DateTime(1969, 10, 1)));
Cursisten.Add(new Cursist(2, "Linthoudt", "Lode", new DateTime(2006, 3, 6)));
Cursisten.Add(new Cursist(3, "Linthoudt", "Emmelie", new DateTime(2009, 8, 12)));
Cursisten.Add(new Cursist(4, "Linthoudt", "Elise", new DateTime(2011, 7, 26)));

De lijst toekennen aan de ListView

Onderstaande code toont hoe u de list kunt toekennen aan de ItemsSource van de ListView.

CursistenLijst.ItemsSource = Cursisten;

De volledige code die de lijst aanmaakt, cursisten toevoegt en toekent aan de ListView:

using System;
using System.Collections.Generic;
using System.Linq;
using Xamarin.Forms;

namespace Lijsten
{
    public partial class MainPage : ContentPage
    {
        List<Cursist> Cursisten = new List<Cursist>();

        public MainPage()
        {
            InitializeComponent();

            Cursisten.Add(new Cursist(1, "Linthoudt", "Geert", new DateTime(1969, 10, 1)));
            Cursisten.Add(new Cursist(2, "Linthoudt", "Lode", new DateTime(2006, 3, 6)));
            Cursisten.Add(new Cursist(3, "Linthoudt", "Emmelie", new DateTime(2009, 8, 12)));
            Cursisten.Add(new Cursist(4, "Linthoudt", "Elise", new DateTime(2011, 7, 26)));

            CursistenLijst.ItemsSource = Cursisten;
        }
    }
}

Toevoegen

Bij het klikken op de knop Toevoegen moet de ContentView zichtbaar worden gemaakt en alle entry in deze ContentView worden leeg gemaakt.

private void BtnToevoegen_Clicked(object sender, EventArgs e)
{
    Cursistnr.Text = string.Empty;
    CursistNaam.Text = string.Empty;
    CursistVoornaam.Text = string.Empty;
    CursistGeboortedatum.Date = DateTime.Today;
    overlay.IsVisible = true;
}

Eens de ContentView in beeld kan op de Annuleren-knop worden geklikt die gewoon de ContentView weer onzichtbaar maakt.

private void BtnAnnuleren_Clicked(object sender, EventArgs e)
{
    overlay.IsVisible = false;
}

Bij het klikken op de OK-knop moet een nieuwe cursist met de ingevulde gegevens worden toegevoegd. Nadat de ContentView terug onzichtbaar is gemaakt.

private void BtnOk_Clicked(object sender, EventArgs e)
{
    overlay.IsVisible = false;
    Cursisten.Add(new Cursist(Convert.ToInt32(Cursistnr.Text), CursistNaam.Text, CursistVoornaam.Text, CursistGeboortedatum.Date));
    CursistenLijst.ItemsSource = null;
    CursistenLijst.ItemsSource = Cursisten;
}

Er bestaat geen “Refresh” om de ListView te vernieuwen. U kunt dit het best in volgende twee stappen doen:

CursistenLijst.ItemsSource = null;
CursistenLijst.ItemsSource = Cursisten;

Verwijderen

Bij het klikken op de Verwijderen-knop moet het geselecteerde item verwijderd worden.

private void BtnVerwijderen_Clicked(object sender, EventArgs e)
{
    if (CursistenLijst.SelectedItem != null)
    {
        Cursisten.Remove((Cursist)CursistenLijst.SelectedItem);
        CursistenLijst.ItemsSource = null;
        CursistenLijst.ItemsSource = Cursisten;
    }

}

Er wordt eerst gecontroleerd of er een item is geselecteerd. Het eigenlijke verwijderen van het gesselecteerde item gebeurt via:

Cursisten.Remove((Cursist)CursistenLijst.SelectedItem);

Opzoeken

Er is een “zoekvak” toegevoegd waar u een deel van de voornaam of achternaam kunt intypen. Tevens wordt de invoer en de op te zoeken waarde naar kleine letters gewijzigd zodat er geen rekening wordt gehouden met hoofdletters. Voor iedere cursist wordt gekeken of hij voldoet aan de zoekwaarde. Indien een cursist voldoet wordt hij geselecteerd.

private void BtnOpzoeken_Clicked(object sender, EventArgs e)
{
    foreach(Cursist c in Cursisten)
    {
        if (TxtZoeken.Text != null && (c.Achternaam.ToLower().Contains(TxtZoeken.Text.ToLower()) || c.Voornaam.ToLower().Contains(TxtZoeken.Text.ToLower())))
        {
            CursistenLijst.SelectedItem = c;
        }
    }
}

Sorteren

Onderstaande LINQ-code sorteert de cursisten op achternaam en voornaam.

private void BtnSorteer_Clicked(object sender, EventArgs e)
{
    var sort = from s in Cursisten orderby s.Achternaam, s.Voornaam select s;

    CursistenLijst.ItemsSource = sort;
}

Info opvragen

Onderstaande code zal onderstaande info opvragen. Merk de async op!

private async void BtnInfo_Clicked(object sender, EventArgs e)
{
    string Uitvoer = null;

    Uitvoer = " De lijst bevat " + Cursisten.Count + " cursisten:" + Environment.NewLine + Environment.NewLine;
    foreach (Cursist i in Cursisten)
    {
        Uitvoer += i.Achternaam + " " + i.Voornaam + Environment.NewLine;
    }

    await DisplayAlert("Info", Uitvoer, "OK");

}

Leeg maken

Onderstaande code maakt de lijst leeg.

private void BtnLeeg_Clicked(object sender, EventArgs e)
{
    Cursisten.Clear();
    CursistenLijst.ItemsSource = null;
    CursistenLijst.ItemsSource = Cursisten;
}

De ListView opmaken

Er wordt een ListView om de gegevens als een lijst weer te geven. De informatie die momenteel getoond wordt komt uit de override van de methode ToString() in de Cursist-klasse.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lijsten
{
    public class Cursist: Persoon
    {
        ...

        public override string ToString()
        {
            return Cursistnummer + ": " + Voornaam + " " + Achternaam + " - " + Geboortedatum.ToString("d");
        }
    }
}

Maar u kunt ook opmaak op maat weergeven.

Hiertoe moet een DataTemplate aan iedere ItemTemplate worden toegevoegd.

<ListView x:Name="CursistenLijst" >
    <ListView.ItemTemplate>
        <DataTemplate>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Vervolgens wordt een ViewCell toegevoegd die een container zoals een StackLayout of een Grid kan bevatten. De gegevens worden vervolgens via een Binding weergegevens in bv. Labels.

<ListView x:Name="CursistenLijst" >
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Orientation="Vertical" Margin="2">
                    <StackLayout Orientation="Horizontal">
                        <Label Text="{Binding Cursistnummer}" TextColor="Black" />
                        <Label Text="{Binding Achternaam}" TextColor="Blue" />
                        <Label Text="{Binding Voornaam}" TextColor="Blue" />
                        <Label Text="{Binding Geboortedatum, StringFormat='{0:dd/MM/yyyy}'}" HorizontalOptions="EndAndExpand" TextColor="Red" />
                    </StackLayout>
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Voor nog meer gevorderde ontwerpen kunt u op de officiële site terecht.


Hoor het eens van iemand anders

Laten we nog eens horen wat Bob Tabor te vertellen heeft over klassen.


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

  • IC BC235 – kan gevorderde principes van programmeren in een specifieke ontwikkelomgeving toepassen
  • IC BC246 – kan complexe ontwerpen in een specifieke ontwikkelomgeving maken

Geef een reactie

  • 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.