De anatomie van een C#-programma – Conditionele weergave (converters)

print

Inhoud


Wat vooraf ging

  • U weet hoe u een Binding tot stand brengt.
  • U weet hoe u een klasse kunt aanmaken.

Conditionele opmaak (converters)

Conditionele opmaak is de opmaak (bv. de kleur) laten afhangen van een bepaalde waarde. Waar een klassieke opmaak (Format) gebruikt wordt alle opmaak zal conditionele opmaak de opmaak slechts toepassen als er aan bepaalde condities voldaan is.

Conditionele opmaak kan gezien worden als een uitbreiding op het Binding-concept. Er wordt gebruikt gemaakt van een klasse die overerft van de klasse iValueConverter.

Converters worden het best zodanig geprogrammeerd zodat ze kunnen hergebruikt worden (DRY-principe) in andere projecten.

Onderstaand voorbeeld vereist dat u minimaal 10 tekens intypt. Zolang u geen 10 tekens ingetypt hebt wordt de lengte in het rood weergegeven, vanaf 10 tekens wordt de lengte in het groen weergegeven.

We hebben dus een converter nodig die getallen gebruikt als waarden voor het omzetten naar kleur. Een gepaste naam zou kunnen zijn IntToColorConverter.

Het programma zonder “converters”.

  • Maak een nieuw Xamarin-project aan en geef het een passende naam (bv. converteren).
  • Voeg onderstaande XAML toe aan MainPage.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" xmlns:local="clr-namespace:Converteren" x:Class="Converteren.MainPage">

    <StackLayout Padding="0,20,0,0">
        <Label Text="Converteren" FontSize="Large" HorizontalOptions="CenterAndExpand"></Label>
        <Label Text="Geef uw antwoord in (minimaal 10 tekens):" />
        <Editor x:Name="editor" HeightRequest="100" Text="" />
        <StackLayout Orientation="Horizontal">
            <Label Text="Aantal tekens:" />
            <Label Text="{Binding Source={x:Reference editor}, Path=Text.Length}" />
        </StackLayout>
        <Button Text="Versturen" HorizontalOptions="Center" />
    </StackLayout>

</ContentPage>

Merk de Binding op tussen de Label en de Editor. De getoonde waarde is Path=Text.Length.
Text="{Binding Source={x:Reference editor}, Path=Text.Length}"

Zet ook al meteen de eigenschap Text="" voor de Editor zodat de binding meteen correct werkt.


De converter implementeren

Converters worden dus gemaakt op basis van de klasse iValueConverter. We moeten dus een klasse toeveogen.

  • Voeg een map met de naam Converters toe die al onze converters zullen bevatten.
  • Voeg, binnen de aangemaakte map Converters, een Klasse toe via rechtsklik op deze map – AddNew item….
  • Kies voor Class en geef het de naam IntToColorConverter.

U krijgt onderstaande klasse.

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

namespace Converteren.Converters
{
    class IntToColorConverter
    {
    }
}
  • Maak de klasse public.
  • Voeg de overerving van iValueConverter toe.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Converteren.Converters
{
    public class IntToColorConverter: iValueConverter
    {
    }
}

Merk op dat dit echter een fout genereert. Gebruik het “lampje” om te achterhalen wat de fout is en deze op te lossen.

De iValueConverter vevindt zich in Xamarin.forms die moet toegevoegd worden via using Xamarin.Forms.

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

namespace Converteren.Converters
{
    public class IntToColorConverter: IValueConverter
    {
    }
}

We zijn er echter nog niet, er wordt nog steeds een fout getoond. De iValueConverter moet nog geïmplementeerd worden. Doe ook dit via het “lampje”.

  • Nu we toch het “lampje” aan het gebruiken zijn kunnen we het ook gebruiken om de “usings” bovenaan op te kuisen.

De code wordt nu:

using System;
using System.Globalization;
using Xamarin.Forms;

namespace Converteren.Converters
{
    public class IntToColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

De Convert-methode wordt aangeroepen telkens een waarde van de bron naar de target wordt doorgegeven.
De ConvertBack-methode wordt aangeroepen telkens een waarde van de target naar de bron wordt doorgegeven.

Beiden methoden kennen volgende argumenten:

public Object Convert (Object value, Type targetType, Object parameter, CultureInfo culture)
public Object ConvertBack (Object value, Type targetType, Object parameter, CultureInfo culture)

  • value – de waarde die moet geconverteerd worden.
  • targetType – het type van de eigenschap die geconverteerd moet worden (de Convert-methode moet een object van dit type teruggeven).
  • parameter – een parameters die kan gebruikt worden tijdens de conversie.
  • culture – eventueel de “cultuur” van de conversie specifiëren.

Als de tekstlengte langer is dan 10 tekens dan moet de kleur groen zijn anders moet de kleur rood zijn. De tekstlengte zal meegegeven worden via het argument value en de controle waarde (hier 10) kan worden meegegeven via het argument parameter.

De Convert-methode zal dus als volgt zijn. Er is geen ConvertBack-methode nodig (die blijft dus ongewijzigd.

using System;
using System.Globalization;
using Xamarin.Forms;

namespace Converteren.Converters
{
    public class IntToColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int minimumLength = Convert.ToInt32(parameter);
            return (int)value >= minimumLength ? Color.Green : Color.Red;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

De converter is nu klaar. Merk op dat deze gemakkelijk kan hergebruikt worden (zolang dezelfde kleuren worden gebruikt).


De converter binden in XAML

Nu de converter geïmplementeerd is moet deze ook nog gebonden worden via XAML.

  • Voeg eerst de namespace naar de converter, u weet nog dat deze zich bevinden in de map Converters, toe xmlns:Converter="clr-namespace:Converteren.Converters".
  • Voeg vervolgens een sleutel (Key) toe naar deze converter binnen de ResourceDictionary.
<?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:Converteren" xmlns:Converter="clr-namespace:Converteren.Converters" x:Class="Converteren.MainPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Converter:IntToColorConverter x:Key="intToColorConverter" />
        </ResourceDictionary>
    </ContentPage.Resources>
    
    <StackLayout Padding="0,20,0,0">
        <Label Text="Converteren" FontSize="Large" HorizontalOptions="CenterAndExpand"></Label>
        <Label Text="Geef uw antwoord in (minimaal 10 tekens):" />
        <Editor x:Name="editor" HeightRequest="100" Text="" />
        <StackLayout Orientation="Horizontal">
            <Label Text="Aantal tekens:" />
            <Label Text="{Binding Source={x:Reference editor}, Path=Text.Length}" />
        </StackLayout>
        <Button Text="Versturen" HorizontalOptions="Center" />
    </StackLayout>

</ContentPage>
  • Voeg de Binding toe aan de property TextColor en voeg tevens de converter toe.

TextColor="{Binding Source={x:Reference editor}, Path=Text.Length, Converter={StaticResource intToColorConverter}, ConverterParameter=10}"

Merk op dat:

  • value = Path=Text.Length.
  • targetType – bepaald wordt door het type van de property waar de binding aan wordt toegekend, hier dus TextColor en het type is dus Color.
  • parameter – de parameter wordt meegegeven via ConverterParameter.
<?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:Converteren" xmlns:Converter="clr-namespace:Converteren.Converters" x:Class="Converteren.MainPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Converter:IntToColorConverter x:Key="intToColorConverter" />
        </ResourceDictionary>
    </ContentPage.Resources>
    
    <StackLayout Padding="0,20,0,0">
        <Label Text="Converteren" FontSize="Large" HorizontalOptions="CenterAndExpand"></Label>
        <Label Text="Geef uw antwoord in (minimaal 10 tekens):" />
        <Editor x:Name="editor" HeightRequest="100" Text="" />
        <StackLayout Orientation="Horizontal">
            <Label Text="Aantal tekens:" />
            <Label Text="{Binding Source={x:Reference editor}, Path=Text.Length}" TextColor="{Binding Source={x:Reference editor}, Path=Text.Length, Converter={StaticResource intToColorConverter}, ConverterParameter=10}" />
        </StackLayout>
        <Button Text="Versturen" HorizontalOptions="Center" />
    </StackLayout>

</ContentPage>

U zou de converter kunnen hergebruiken en verbinden met de property BackgroundColor van de Editor.

BackgroundColor="{Binding Source={x:Reference editor}, Path=Text.Length, Converter={StaticResource intToColorConverter}, ConverterParameter=10}"/>

<?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:Converteren" xmlns:Converter="clr-namespace:Converteren.Converters" x:Class="Converteren.MainPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Converter:IntToColorConverter x:Key="intToColorConverter" />
        </ResourceDictionary>
    </ContentPage.Resources>
    
    <StackLayout Padding="0,20,0,0">
        <Label Text="Converteren" FontSize="Large" HorizontalOptions="CenterAndExpand"></Label>
        <Label Text="Geef uw antwoord in (minimaal 10 tekens):" />
        <Editor x:Name="editor" HeightRequest="100" Text="" BackgroundColor="{Binding Source={x:Reference editor}, Path=Text.Length, Converter={StaticResource intToColorConverter}, ConverterParameter=10}"/>
        <StackLayout Orientation="Horizontal">
            <Label Text="Aantal tekens:" />
            <Label Text="{Binding Source={x:Reference editor}, Path=Text.Length}" TextColor="{Binding Source={x:Reference editor}, Path=Text.Length, Converter={StaticResource intToColorConverter}, ConverterParameter=10}" />
        </StackLayout>
        <Button Text="Versturen" HorizontalOptions="Center" />
    </StackLayout>

</ContentPage>


Een tweede converter toevoegen

U wilt nu ook dat u enkel de knop Versturen kunt aanklikken indien er meer dan 10 tekens zijn ingetypt.

We hebben dus een converter nodig die getallen gebruikt als waarden voor het omzetten naar een boolean. Een gepaste naam zou kunnen zijn IntToBooleanConverter.

  • Implementeer de converter IntToBooleanConverter.
using System;
using System.Globalization;
using Xamarin.Forms;

namespace Converteren.Converters
{
    public class IntToBooleanConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int minimumLength = Convert.ToInt32(parameter);
            return (int)value >= minimumLength;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
  • Verbind de converter, met de property IsEnabled in XAML. Vergeet niet de Key toe te voegen.

IsEnabled="{Binding Source={x:Reference editor}, Path=Text.Length, Converter={StaticResource intToBooleanConverter}, ConverterParameter=10}"

<?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:Converteren" xmlns:Converter="clr-namespace:Converteren.Converters" x:Class="Converteren.MainPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Converter:IntToColorConverter x:Key="intToColorConverter" />
            <Converter:IntToBooleanConverter x:Key="intToBooleanConverter" />
        </ResourceDictionary>
    </ContentPage.Resources>
    
    <StackLayout Padding="0,20,0,0">
        <Label Text="Converteren" FontSize="Large" HorizontalOptions="CenterAndExpand"></Label>
        <Label Text="Geef uw antwoord in (minimaal 10 tekens):" />
        <Editor x:Name="editor" HeightRequest="100" Text="" BackgroundColor="{Binding Source={x:Reference editor}, Path=Text.Length, Converter={StaticResource intToColorConverter}, ConverterParameter=10}"/>
        <StackLayout Orientation="Horizontal">
            <Label Text="Aantal tekens:" />
            <Label Text="{Binding Source={x:Reference editor}, Path=Text.Length}" TextColor="{Binding Source={x:Reference editor}, Path=Text.Length, Converter={StaticResource intToColorConverter}, ConverterParameter=10}" />
        </StackLayout>
        <Button Text="Versturen" HorizontalOptions="Center" IsEnabled="{Binding Source={x:Reference editor}, Path=Text.Length, Converter={StaticResource intToBooleanConverter}, ConverterParameter=10}"/>
    </StackLayout>

</ContentPage>


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

  • IC BC017 – kan ICT veilig en duurzaam gebruiken
  • IC BC231 – kan modellen, simulaties of visualisaties van de realiteit maken
  • 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.