Mobiele apps programmeren met Xamarin – XAML optimalisatie volgens het DRY-principe – Stijlen

print

Inhoud


Wat vooraf ging

Opmerking, om de één of andere duistere reden lijnt WordPress de stijl-code niet juist uit waardoor sommige code er wat chaotisch opgemaakt lijkt.


Wat zijn stijlen?

Een stijl is een verzameling van opmaakcode waaraan een naam toegekend wordt. Dit laat toe om dezelfde stijl, door een simpele aanroep van deze stijl, op verschillende objecten in het project toe te passen. Veranderen we de stijl dan zal dit meteen zichtbaar worden op alle objecten die deze stijl toepassen.

Een stijl wordt aangemaakt als een Style-element:



<Style></Style>


Een stijl kent twee typen:

  • impliciet: van toepassing op alle elementen van een bepaald type (het type moet worden aangegeven met bv. TargetType="Label").
  • expliciet: enkel van toepassing wanneer de stijl expliciet bij naam aangeroepen wordt (de stijl bevat nu zowel het type als een naam/key bv. x:Key="labelStyle" TargetType="Label").

Waar plaatst u stijlen?

Stijlen worden geplaatst in een ResourceDictionary. Wilt u dat de stijl gekend is in heel uw project (we spreken van een globale stijl) dan wordt de stijl geplaatst in het bestand App.xaml.

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="TestStijlen.App">
	<Application.Resources>

		<!-- Application resource dictionary -->

	</Application.Resources>
</Application>

Is de stijl eerder gebonden aan een specifieke pagina, of een specifieke lay-out, dan plaatst u de stijl hierbinnen. bijvoorbeeld binnen de pagina:

<?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:TestStijlen" x:Class="TestStijlen.MainPage">
    
    <ContentPage.Resources>
        <ResourceDictionary>

        </ResourceDictionary>
    </ContentPage.Resources>
    
</ContentPage>

Weet dat wanneer u eenzelfde stijl op meerdere niveaus aanmaakt de stijl het dichts bij gebruikt wordt. Dus, een stijl gemaakt in een lay-out (bv. StackLayout) heeft voorrang op eenzelfde stijl gemaakt op paginaniveau en deze heeft dan weer voorrang op eenzelfde stijl gemaakt op applicatieniveau.


Impliciete stijlen

Een stijl vereenvoudigt dus niet enkel de code maar maakt vooral code gemakkelijk herbruikbaar en aanpasbaar (het Dry-principe). We illustreren dit met een voorbeeld.

  • Start een nieuw Xamarin-project en geef het een passende naam (bv. TestStijlen).
  • Voeg onderstaande onderstaande XAML toe aan de 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:TestStijlen" x:Class="TestStijlen.MainPage">

    <StackLayout Padding="0,20,0,0">
        <Label Text="PCVO Dender en Schelde" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" FontSize="Large" />
        <Label Text="Volwassenenonderwijs" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" FontSize="Large" />
        <Label Text="Ninove - Oudenaarde - Zottegem" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" FontSize="Large" />
    </StackLayout>

</ContentPage>

Merk op dat eenzelfde code herhaald wordt en… Don’t Repeat Yourself (Dry-principe)!

We kunnen dus de herhalende opmaak afzonderen in een stijl.

De stijl de we maken zal van toepassing zijn op alle Labels binnen deze pagina. De stijl wordt dan ook toegevoegd aan de ResourceDictionary van de pagina.

<?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:TestStijlen" x:Class="TestStijlen.MainPage">
    
    <ContentPage.Resources>
        <ResourceDictionary>

        </ResourceDictionary>
    </ContentPage.Resources>
    
    <StackLayout Padding="0,20,0,0">
        <Label Text="PCVO Dender en Schelde" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" FontSize="Large" />
        <Label Text="Volwassenenonderwijs" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" FontSize="Large" />
        <Label Text="Ninove - Oudenaarde - Zottegem" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" FontSize="Large" />
    </StackLayout>

</ContentPage>

Omdat de stijl gebruikt wordt voor alle Labels kan een impliciete stijl gebruikt worden en wordt enkel de eigenschap TargetType="Label" ingesteld.



<Style TargetType="Label">

</Style>


De code wordt nu:

<?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:TestStijlen" x:Class="TestStijlen.MainPage">
    
    <ContentPage.Resources>
        <ResourceDictionary>    
            
            
<Style TargetType="Label">

            </Style>


        </ResourceDictionary>
    </ContentPage.Resources>
    
    <StackLayout Padding="0,20,0,0">
        <Label Text="PCVO Dender en Schelde" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" FontSize="Large" />
        <Label Text="Volwassenenonderwijs" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" FontSize="Large" />
        <Label Text="Ninove - Oudenaarde - Zottegem" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" FontSize="Large" />
    </StackLayout>

</ContentPage>

De stijl zelf bevat nu een reeks instellingen (Setter) die een Property een Value toekent. Bijvoorbeeld.

<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
<Setter Property="FontSize" Value="Large" />

De finale code wordt nu:

<?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:TestStijlen" x:Class="TestStijlen.MainPage">
    
    <ContentPage.Resources>
        <ResourceDictionary>
            
            
<Style TargetType="Label">
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                <Setter Property="FontSize" Value="Large" />
            </Style>


        </ResourceDictionary>
    </ContentPage.Resources>
    
    
    <StackLayout Padding="0,20,0,0">
        <Label Text="PCVO Dender en Schelde"/>
        <Label Text="Volwassenenonderwijs" />
        <Label Text="Ninove - Oudenaarde - Zottegem"/>
    </StackLayout>

</ContentPage>

C#

Hoewel stijlen het gemakkelijkste in XAML worden aangemaakt kunt u ze ook in C# aanmaken. Onderstaande C#-code doet hetzelfde als bovenstaande XAML.

using Xamarin.Forms;

namespace TestStijlen
{
    public class ImplicieteStijlC : ContentPage
    {
        public ImplicieteStijlC()
        {
            var labelStyle = new Style(typeof(Label))
            {
                Setters = {
                    new Setter {
                        Property = View.HorizontalOptionsProperty,
                        Value = LayoutOptions.Center
                    },
                    new Setter {
                        Property = View.VerticalOptionsProperty,
                        Value = LayoutOptions.CenterAndExpand
                    },
                    new Setter {
                        Property = Label.FontSizeProperty,
                        Value = Device.GetNamedSize (NamedSize.Large, typeof(Label))
                    }
                }
            };

            Resources = new ResourceDictionary();
            Resources.Add(labelStyle);

            Content = new StackLayout
            {
                Children = {
                new Label { Text = "PCVO Dender en Schelde" },
                new Label { Text = "Volwassenenonderwijs" },
                new Label { Text = "Ninove - Oudenaarde - Zottegem" },
                }
            };
        }
    }
}

Expliciete stijlen

Een impliciete stijl wordt toegepast op alle elementen van een type, bv. op alle Labels, op alle Buttons,…

Maar soms wilt u niet dat alle Labels, alle Buttons,… eenzelfde stijl krijgen maar dat slechts sommige Labels, Buttons,… eenzelfde stijl krijgen en andere Labels, Buttons,… een andere stijl.

Om dit te kunnen moeten de stijlen expliciet aangemaakt worden door ze een naam/key toe te kennen x:Key="GrootRood".

Hieronder ziet u 2 expliciete stijlen.

<ContentPage.Resources>
    <ResourceDictionary>      
        
        
<Style x:Key="GrootRood" TargetType="Label">
            <Setter Property="HorizontalOptions" Value="Center" />
            <Setter Property="VerticalOptions" Value="CenterAndExpand" />
            <Setter Property="FontSize" Value="Large" />
            <Setter Property="TextColor" Value="Red" />
        </Style>


        
        
<Style x:Key="KleinGroen" TargetType="Label">
            <Setter Property="HorizontalOptions" Value="Center" />
            <Setter Property="VerticalOptions" Value="CenterAndExpand" />
            <Setter Property="FontSize" Value="Small" />
            <Setter Property="TextColor" Value="Green" />
        </Style>


    </ResourceDictionary>
</ContentPage.Resources>

Deze stijlen dienen dan ook expliciet aangeroepen te worden d.m.v. hun naam/key. Aangezien de stijlen niet gewijzigd mogen/moeten worden, worden ze statisch aangeroepen met Style="{StaticResource GrootRood}".

Hieronder ziet u hoe de bovenstaande stijlen aangeroepen worden.

<Label Text="PCVO Dender en Schelde" Style="{StaticResource GrootRood}"/>
<Label Text="Volwassenenonderwijs" Style="{StaticResource GrootRood}"/>
<Label Text="Ninove - Oudenaarde - Zottegem" Style="{StaticResource KleinGroen}"/>

De volledige XAML is:

<?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="TestStijlen.ExplicieteStijl">

    <ContentPage.Resources>
        <ResourceDictionary>
           
            
<Style x:Key="GrootRood" TargetType="Label">
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                <Setter Property="FontSize" Value="Large" />
                <Setter Property="TextColor" Value="Red" />
            </Style>

   
            
<Style x:Key="KleinGroen" TargetType="Label">
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                <Setter Property="FontSize" Value="Small" />
                <Setter Property="TextColor" Value="Green" />
            </Style>


        </ResourceDictionary>
    </ContentPage.Resources>


    <StackLayout Padding="0,20,0,0">
        <Label Text="PCVO Dender en Schelde" Style="{StaticResource GrootRood}"/>
        <Label Text="Volwassenenonderwijs" Style="{StaticResource GrootRood}"/>
        <Label Text="Ninove - Oudenaarde - Zottegem" Style="{StaticResource KleinGroen}"/>
    </StackLayout>

</ContentPage>

C#

using Xamarin.Forms;

namespace TestStijlen
{
    public class ExplicieteStijlC : ContentPage
    {
        public ExplicieteStijlC()
        {
            var GrootRood = new Style(typeof(Label))
            {
                Setters = {
                    new Setter {
                        Property = View.HorizontalOptionsProperty,
                        Value = LayoutOptions.Center
                    },
                    new Setter {
                        Property = View.VerticalOptionsProperty,
                        Value = LayoutOptions.CenterAndExpand
                    },
                    new Setter {
                        Property = Label.FontSizeProperty,
                        Value = Device.GetNamedSize (NamedSize.Large, typeof(Label))
                    },
                    new Setter {
                        Property = Label.TextColorProperty,
                        Value = Color.Red  }
                }
            };

            var KleinGroen = new Style(typeof(Label))
            {
                Setters = {
                    new Setter {
                        Property = View.HorizontalOptionsProperty,
                        Value = LayoutOptions.Center
                    },
                    new Setter {
                        Property = View.VerticalOptionsProperty,
                        Value = LayoutOptions.CenterAndExpand
                    },
                    new Setter {
                        Property = Label.FontSizeProperty,
                        Value = Device.GetNamedSize (NamedSize.Small, typeof(Label))
                    },
                    new Setter {
                        Property = Label.TextColorProperty,
                        Value = Color.Green  
                    }
                }
            };

            Resources = new ResourceDictionary();
            Resources.Add("GrootRood", GrootRood);
            Resources.Add("KleinGroen", KleinGroen);

            Content = new StackLayout
            {
                Children = {
                new Label { Text = "PCVO Dender en Schelde", Style = (Style)Resources ["GrootRood"] },
                new Label { Text = "Volwassenenonderwijs", Style = (Style)Resources ["GrootRood"] },
                new Label { Text = "Ninove - Oudenaarde - Zottegem", Style = (Style)Resources ["KleinGroen"] },
                }
            };
        }
    }
}

Expliciete stijlen hoeven niet opgenomen in de Resources. De bovenstaande code kan dus als volgt vereenvoudigd worden.

using Xamarin.Forms;

namespace TestStijlen
{
    public class ExplicieteStijlC : ContentPage
    {
        public ExplicieteStijlC()
        {
            var GrootRood = new Style(typeof(Label))
            {
                Setters = {
                    new Setter {
                        Property = View.HorizontalOptionsProperty,
                        Value = LayoutOptions.Center
                    },
                    new Setter {
                        Property = View.VerticalOptionsProperty,
                        Value = LayoutOptions.CenterAndExpand
                    },
                    new Setter {
                        Property = Label.FontSizeProperty,
                        Value = Device.GetNamedSize (NamedSize.Large, typeof(Label))
                    },
                    new Setter {
                        Property = Label.TextColorProperty,
                        Value = Color.Red  }
                }
            };

            var KleinGroen = new Style(typeof(Label))
            {
                Setters = {
                    new Setter {
                        Property = View.HorizontalOptionsProperty,
                        Value = LayoutOptions.Center
                    },
                    new Setter {
                        Property = View.VerticalOptionsProperty,
                        Value = LayoutOptions.CenterAndExpand
                    },
                    new Setter {
                        Property = Label.FontSizeProperty,
                        Value = Device.GetNamedSize (NamedSize.Small, typeof(Label))
                    },
                    new Setter {
                        Property = Label.TextColorProperty,
                        Value = Color.Green  
                    }
                }
            };

            Content = new StackLayout
            {
                Children = {
                new Label { Text = "PCVO Dender en Schelde", Style = GrootRood },
                new Label { Text = "Volwassenenonderwijs", Style = GrootRood },
                new Label { Text = "Ninove - Oudenaarde - Zottegem", Style = KleinGroen },

                }
            };
        }
    }
}

Een stijl baseren op een andere stijl

We kunnen het DRY-principe nog verder toepassen. Als u immers de stijlen bekijkt dan ziet u ook hier terugkerende code.



<Style x:Key="GrootRood" TargetType="Label">
    <Setter Property="HorizontalOptions" Value="Center" />
    <Setter Property="VerticalOptions" Value="CenterAndExpand" />
    <Setter Property="FontSize" Value="Large" />
    <Setter Property="TextColor" Value="Red" />
</Style>



<Style x:Key="KleinGroen" TargetType="Label">
    <Setter Property="HorizontalOptions" Value="Center" />
    <Setter Property="VerticalOptions" Value="CenterAndExpand" />
    <Setter Property="FontSize" Value="Small" />
    <Setter Property="TextColor" Value="Green" />
</Style>

Merk dat beide stijlen dezelfde setter hebben.

<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="CenterAndExpand" />

Dus, ook deze herhalende code zouden we volgens het DRY-principe moeten kunnen afzonderen. u kunt dit doen door een stijl te baseren op een andere stijl (inheritance)

Maak gewoon een stijl aan zoals u hierboven geleerd hebt en plaats er de herhalende setters in.


<Style x:Key="Centreren" TargetType="View" >
    <Setter Property="HorizontalOptions" Value="Center" />
    <Setter Property="VerticalOptions" Value="CenterAndExpand" />
</Style>

Merk op, door het TargetType="View" kunt u alle elementen gebaseerd op het type View ook laten “erven” van deze stijl.

Vervolgens kunt u andere stijlen baseren op deze stijl met BasedOn="{StaticResource Centreren}".


<Style x:Key="GrootRood" TargetType="Label" BasedOn="{StaticResource Centreren}">
    <Setter Property="FontSize" Value="Large" />
    <Setter Property="TextColor" Value="Red" />
</Style>

In onderstaande, “volledige” code heb ik ook een Button toegevoegd.

<?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="TestStijlen.ExplicieteStijl">

    <ContentPage.Resources>
        <ResourceDictionary>
            
            
<Style x:Key="Centreren" TargetType="View" >
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
            </Style>

  
            
<Style x:Key="GrootRood" TargetType="Label" BasedOn="{StaticResource Centreren}">
                <Setter Property="FontSize" Value="Large" />
                <Setter Property="TextColor" Value="Red" />
            </Style>

 
            
<Style x:Key="KleinGroen" TargetType="Label" BasedOn="{StaticResource Centreren}" >
                <Setter Property="FontSize" Value="Small" />
                <Setter Property="TextColor" Value="Green" />
            </Style>

            
<Style x:Key="GrootBlauw" TargetType="Button" BasedOn="{StaticResource Centreren}" >
                <Setter Property="FontSize" Value="Large" />
                <Setter Property="TextColor" Value="Blue" />
            </Style>


        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout Padding="0,20,0,0">
        <Label Text="PCVO Dender en Schelde" Style="{StaticResource GrootRood}"/>
        <Label Text="Volwassenenonderwijs" Style="{StaticResource GrootRood}"/>
        <Label Text="Ninove - Oudenaarde - Zottegem" Style="{StaticResource KleinGroen}"/>
        <Button Text="OK" Style="{StaticResource GrootBlauw}"></Button>
    </StackLayout>

</ContentPage>

C#

using Xamarin.Forms;

namespace TestStijlen
{
    public class ExplicieteStijlC : ContentPage
    {
        public ExplicieteStijlC()
        {
            var Centreren = new Style(typeof(View))
            {
                Setters = {
                    new Setter {
                        Property = View.HorizontalOptionsProperty,
                        Value = LayoutOptions.Center
                    },
                    new Setter {
                        Property = View.VerticalOptionsProperty,
                        Value = LayoutOptions.CenterAndExpand
                    }
                }
            };

            var GrootRood = new Style(typeof(Label))
            {
                BasedOn = Centreren,
                Setters = {
                    new Setter {
                        Property = Label.FontSizeProperty,
                        Value = Device.GetNamedSize (NamedSize.Large, typeof(Label))
                    },
                    new Setter {
                        Property = Label.TextColorProperty,
                        Value = Color.Red  }
                }
            };

            var KleinGroen = new Style(typeof(Label))
            {
                BasedOn = Centreren,
                Setters = {
                    new Setter {
                        Property = Label.FontSizeProperty,
                        Value = Device.GetNamedSize (NamedSize.Small, typeof(Label))
                    },
                    new Setter {
                        Property = Label.TextColorProperty,
                        Value = Color.Green  }
                }
            };

            var GrootBlauw = new Style(typeof(Button))
            {
                BasedOn = Centreren,
                Setters = {
                    new Setter {
                        Property = Button.FontSizeProperty,
                        Value = Device.GetNamedSize (NamedSize.Large, typeof(Button))
                    },
                    new Setter {
                        Property = Button.TextColorProperty,
                        Value = Color.Blue  }
                }
            };

            Content = new StackLayout
            {
                Children = {
                new Label { Text = "PCVO Dender en Schelde", Style = GrootRood },
                new Label { Text = "Volwassenenonderwijs", Style = GrootRood },
                new Label { Text = "Ninove - Oudenaarde - Zottegem", Style = KleinGroen },
                new Button { Text = "OK", Style = GrootBlauw },

                }
            };
        }
    }
}

Dynamische stijlen

De stijlen die we tot nu toe gebruikt hebben waren statisch. Ze werden dus toegekend en konden nadien niet meer gewijzigd worden. U kunt echter ook stijlen dynamisch aanroepen via Style="{DynamicResource searchBarStyle}". Het wijzigen van de stijl gebeurt via code-behind.

Onderstaande code demonstreert dynamische stijlen.


<?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="TestStijlen.DynamischeStijlen">

    <ContentPage.Resources>
        <ResourceDictionary>
            
            
<Style x:Key="baseStyle" TargetType="View">
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
            </Style>

       
            
<Style x:Key="blueSearchBarStyle" TargetType="SearchBar" BasedOn="{StaticResource baseStyle}">
                <Setter Property="FontAttributes" Value="Italic" />
                <Setter Property="PlaceholderColor" Value="Blue" />
            </Style>

      
            
<Style x:Key="greenSearchBarStyle" TargetType="SearchBar">
                <Setter Property="FontAttributes" Value="None" />
                <Setter Property="PlaceholderColor" Value="Green" />
            </Style>

        
            
<Style x:Key="buttonStyle" TargetType="Button" BasedOn="{StaticResource baseStyle}">
                <Setter Property="FontSize" Value="Large" />
                <Setter Property="TextColor" Value="Red" />
            </Style>


        </ResourceDictionary>
    </ContentPage.Resources>
    
    <StackLayout Padding="0,20,0,0">
        <SearchBar Placeholder="These SearchBar controls" Style="{DynamicResource searchBarStyle}" />
        <SearchBar Placeholder="are demonstrating" Style="{DynamicResource searchBarStyle}" />
        <SearchBar Placeholder="dynamic styles," Style="{DynamicResource searchBarStyle}" />
        <SearchBar Placeholder="but this isn't dynamic" Style="{StaticResource blueSearchBarStyle}" />
        <Button Text="Change Style" Style="{StaticResource buttonStyle}" Clicked="OnButtonClicked" />
        </StackLayout>

</ContentPage>

Merk op dat de stijl Style="{DynamicResource searchBarStyle} nergens is gedefinieerd, deze wordt via code-behind toegekend.

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

namespace TestStijlen
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class DynamischeStijlen : ContentPage
    {
        bool originalStyle = true;
        public DynamischeStijlen()
        {
            InitializeComponent();
            Resources["searchBarStyle"] = Resources["blueSearchBarStyle"];
        }

        private void OnButtonClicked(object sender, EventArgs e)
        {
            if (originalStyle)
            {
                Resources["searchBarStyle"] = Resources["greenSearchBarStyle"];
                originalStyle = false;
            }
            else
            {
                Resources["searchBarStyle"] = Resources["blueSearchBarStyle"];
                originalStyle = true;
            }

        }
    }
}

C#

Dezelfde code in C#.

using System;
using Xamarin.Forms;

namespace TestStijlen
{
    public class DynamischeStijlenC : ContentPage
    {
        bool originalStyle = true;
        public DynamischeStijlenC()
        {
            Padding = new Thickness(0, 20, 0, 0);

            var baseStyle = new Style(typeof(View))
            {
                Setters = {
                    new Setter {
                        Property = View.VerticalOptionsProperty,
                        Value = LayoutOptions.CenterAndExpand
                    }
                }
            };

            var blueSearchBarStyle = new Style(typeof(SearchBar))
            {
                BasedOn = baseStyle,
                Setters = {
                    new Setter {
                        Property = SearchBar.FontAttributesProperty,
                        Value = FontAttributes.Italic
                    },
                    new Setter {
                        Property = SearchBar.PlaceholderColorProperty,
                        Value = Color.Blue
                    }
                }
            };

            var greenSearchBarStyle = new Style(typeof(SearchBar))
            {
                Setters = {
                    new Setter {
                        Property = SearchBar.FontAttributesProperty,
                        Value = FontAttributes.None
                    },
                    new Setter {
                        Property = SearchBar.PlaceholderColorProperty,
                        Value = Color.Green
                    }
                }
            };

            var buttonStyle = new Style(typeof(Button))
            {
                BasedOn = baseStyle,
                Setters = {
                    new Setter {
                        Property = Button.FontSizeProperty,
                        Value = Device.GetNamedSize (NamedSize.Large,
                                typeof(Button))
                    },
                    new Setter {
                        Property = Button.TextColorProperty,
                        Value = Color.Red
                    }
                }
            };

            var searchBar1 = new SearchBar
            {
                Placeholder = "These SearchBar controls"
            };
            searchBar1.SetDynamicResource(VisualElement.StyleProperty, "searchBarStyle");
            var searchBar2 = new SearchBar
            {
                Placeholder = "are demonstrating"
            };
            searchBar2.SetDynamicResource(VisualElement.StyleProperty, "searchBarStyle");
            var searchBar3 = new SearchBar
            {
                Placeholder = "dynamic styles, "
            };
            searchBar3.SetDynamicResource(VisualElement.StyleProperty, "searchBarStyle");
            var searchBar4 = new SearchBar
            {
                Placeholder = "but this isn't dynamic",
                Style = blueSearchBarStyle
            };

            var button = new Button
            {
                Text = "Change Style",
                Style = buttonStyle
            };

            button.Clicked += OnButtonClicked;

            Resources = new ResourceDictionary();
            Resources.Add("blueSearchBarStyle", blueSearchBarStyle);
            Resources.Add("greenSearchBarStyle", greenSearchBarStyle);
            Resources["searchBarStyle"] = Resources["blueSearchBarStyle"];

            Content = new StackLayout
            {
                Children = {
                    searchBar1,
                    searchBar2,
                    searchBar3,
                    searchBar4,
                    button
                }
            };
        }

        void OnButtonClicked(object sender, EventArgs e)
        {
            if (originalStyle)
            {
                Resources["searchBarStyle"] =
                    Resources["greenSearchBarStyle"];
                originalStyle = false;
            }
            else
            {
                Resources["searchBarStyle"] =
                    Resources["blueSearchBarStyle"];
                originalStyle = true;
            }
        }
    }
}

Dynamisch overerven

Een stijl overerven van een dynamische stijl kan niet via BasedOn. In plaats hiervan wordt BaseResourceKey gebruikt.




<Style x:Key="tealSearchBarStyle" TargetType="SearchBar" BaseResourceKey="searchBarStyle">
    <Setter Property="BackgroundColor" Value="Teal" />
    <Setter Property="CancelButtonColor" Value="White" />
</Style>



Device stijlen

Xamarin komt met een aantal standaard dynamische device stijlen die u kunt toepassen op Labels.

  • BodyStyle
  • CaptionStyle
  • ListItemDetailTextStyle
  • ListItemTextStyle
  • SubtitleStyle
  • TitleStyle

<?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="TestStijlen.TestDeviceStijlen">
    <ContentPage.Resources>
        <ResourceDictionary>
        
        
<Style x:Key="myBodyStyle" TargetType="Label" BaseResourceKey="BodyStyle">
            <Setter Property="TextColor" Value="Accent" />
        </Style>


    </ResourceDictionary>
    </ContentPage.Resources>
        <StackLayout Padding="0,20,0,0">
            <Label Text="Title style" Style="{DynamicResource TitleStyle}" />
            <Label Text="Subtitle style" Style="{DynamicResource SubtitleStyle}" />
            <Label Text="Body style" Style="{DynamicResource BodyStyle}" />
            <Label Text="Caption style" Style="{DynamicResource CaptionStyle}" />
            <Label Text="List item detail text style" Style="{DynamicResource ListItemDetailTextStyle}" />
            <Label Text="List item text style" Style="{DynamicResource ListItemTextStyle}" />
            <Label Text="No style" />
            <Label Text="My body style" Style="{StaticResource myBodyStyle}" />
        </StackLayout>

</ContentPage>

C#

Dezelfde code in C#.

using Xamarin.Forms;

namespace TestStijlen
{
    public class TestDeviceStijlenC : ContentPage
    {
        public TestDeviceStijlenC()
        {
            var myBodyStyle = new Style(typeof(Label))
            {
                BaseResourceKey = Device.Styles.BodyStyleKey,
                Setters = {
                    new Setter {
                        Property = Label.TextColorProperty,
                        Value = Color.Accent
                    }
                }
            };

            Padding = new Thickness(0, 20, 0, 0);

            Content = new StackLayout
            {
                Children = {
                new Label {
                            Text = "Title style",
                            Style = Device.Styles.TitleStyle
                        },
                new Label {
                            Text = "Subtitle style",
                            Style = Device.Styles.SubtitleStyle
                        },
                new Label {
                            Text = "Body style",
                            Style = Device.Styles.BodyStyle
                        },
                new Label {
                            Text = "Caption style",
                            Style = Device.Styles.CaptionStyle
                        },
                new Label {
                            Text = "List item detail text style",
                            Style = Device.Styles.ListItemDetailTextStyle
                        },
                new Label {
                            Text = "List item text style",
                            Style = Device.Styles.ListItemTextStyle
                        },
                new Label {
                            Text = "No style"
                        },
                new Label {
                            Text = "My body style",
                            Style = myBodyStyle
                        }
                }
            };

        }
    }
}

Triggers

Triggers laat toe om, via XAML, instellingen te wijzigen wanneer er zich iets voordoet. BV. als een Entry de focus krijgt moet de opmaak wijzigen.

Er zijn 4 soorten triggers:

  • Property Trigger – wanneer een property van een element een bepaalde waarde krijgt.
  • Data Trigger – gebruik databinding op de verandering van een property van een element.
  • Event Trigger – wanneer een event/gebeurtenis wordt uitgevoerd op een element.
  • Multi Trigger – laat toe om meerdere condities in te stellen.

We bespreken hier enkel de Property Trigger.

Een trigger kan geplaatst worden bij het object zelf. Triggers worden toegevoegd via Entry.Triggers.

<Entry Placeholder="enter name">
  <Entry.Triggers>

  </Entry.Triggers>
</Entry>

De Trigger bevat een Trigger die aangeeft welke property welke waarde moet hebben.

<Entry Placeholder="enter name">
  <Entry.Triggers>
      <Trigger TargetType="Entry" Property="IsFocused" Value="True">

      </Trigger>
  </Entry.Triggers>
</Entry>

Vervolgens wordt een Setter toegevoegd die wordt toegevoegd indien de Trigger euh, getriggerd wordt.

<Entry Placeholder="enter name">
  <Entry.Triggers>
    <Trigger TargetType="Entry" Property="IsFocused" Value="True">
      <Setter Property="BackgroundColor" Value="Yellow" />
    </Trigger>
  </Entry.Triggers>
</Entry>

Triggers kunnen ook worden toegevoegd binnen een stijl.

<ContentPage.Resources>
  <ResourceDictionary>
    
    
<Style TargetType="Entry">
      <Style.Triggers>
        <Trigger TargetType="Entry" Property="IsFocused" Value="True">
          <Setter Property="BackgroundColor" Value="Yellow" />
        </Trigger>
      </Style.Triggers>
    </Style>


  </ResourceDictionary>
</ContentPage.Resources>

Voorbeeld

In onderstaand voorbeeld wordt de Entry met 1.5 geschaald als hij de focus krijgt Property="IsFocused" Value="True".

Zonder stijl

<?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="TestStijlen.TestTrigger">

    <StackLayout Spacing="20">
        <Entry Placeholder="enter name" AnchorX="0">
            <Entry.Triggers>
                <Trigger TargetType="Entry" Property="IsFocused" Value="True">
                    <Setter Property="Scale" Value="1.5" />
                </Trigger>
            </Entry.Triggers>
        </Entry>

        <Entry Placeholder="enter address" AnchorX="0">
            <Entry.Triggers>
                <Trigger TargetType="Entry" Property="IsFocused" Value="True">
                    <Setter Property="Scale" Value="1.5" />
                </Trigger>
            </Entry.Triggers>
        </Entry>

        <Entry Placeholder="enter city and state" AnchorX="0">
            <Entry.Triggers>
                <Trigger TargetType="Entry" Property="IsFocused" Value="True">
                    <Setter Property="Scale" Value="1.5" />
                </Trigger>
            </Entry.Triggers>
        </Entry>
    </StackLayout>

</ContentPage>

Met een stijl

<?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="TestStijlen.TestTrigger">

    <ContentPage.Resources>
        <ResourceDictionary>
           
            
<Style TargetType="Entry">
                <Setter Property="AnchorX" Value="0" />
                <Style.Triggers>
                    <Trigger TargetType="Entry" Property="IsFocused" Value="True">
                        <Setter Property="Scale" Value="1.5" />
                    </Trigger>
                </Style.Triggers>
            </Style>


        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout Spacing="20">
        <Entry Placeholder="enter name" />
        <Entry Placeholder="enter address" />
        <Entry Placeholder="enter city and state" />
    </StackLayout>


</ContentPage>

Merk AnchorX="0" op. Dit verankert het element aan de linkerzijde (x = 0). Laat u dit weg dan zou door de schaling een deel van de Entry buiten de pagina vallen.


Hoor het eens van iemand anders

Onderstaande video neemt ons opnieuw mee naar Xamarin University met een lesje over stijlen en trigger.


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

  • IC BC253 – kan broncode in een specifieke ontwikkelomgeving optimaliseren

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.