Als het gaat om het ontwerpen en indelen van de schermen van uw toepassing, hebt u twee hoofdopties, code schrijven of XAML gebruiken. Als je ooit een WPF (Windows Presentation Foundation) of Silverlight-ontwikkeling hebt gedaan, dan ben je waarschijnlijk al bekend met XAML. XAML is het eXtensible Application Markup Language die is gemaakt om het uiterlijk van een toepassing te bepalen zonder alles in code te hoeven verwerken. Xamarin.Forms werkt met beide opties. Het is uiteindelijk aan u om te beslissen welke optie u verkiest.
Het is belangrijk op te merken dat de XAML die wordt gebruikt voor Xamarin.Forms niet compatibel is met andere vormen van XAML- en XAML-tools.
Als je het type persoon bent dat graag in de code zit en niets te maken wil hebben met een soort markup of een ontwerper, dan zul je waarschijnlijk heel comfortabel zijn met deze optie. U programmeert automatisch verschillende typen Uitzicht
objecten en voeg ze rechtstreeks toe aan een Pagina
of om een lay-out
op een Pagina
. Hier is een eenvoudig voorbeeld van het maken van een SimplePage
klas, een paar instantiatieven Uitzicht
objecten, en ze toe te voegen aan de Pagina
door een stackLayout
voorwerp.
public class SamplePage: ContentPage public SamplePage () Opvulling = nieuwe dikte (20); var label = new Label Text = "Ik ben een eenvoudige pagina", BackgroundColor = Color.Blue, Font = Font.SystemFontOfSize (30), WidthRequest = 150, HeightRequest = 40; var button = new Button Text = "Ik heb een knop", BackgroundColor = Color.Red, Font = Font.SystemFontOfSize (20), WidthRequest = 200, HeightRequest = 200; var entry = new Entry Placeholder = "Ik heb een invoervak", BackgroundColor = Color.Green, WidthRequest = 200, HeightRequest = 150; Inhoud = nieuwe StackLayout Spacing = 10, Children = button, entry, label;
Zoals u kunt zien, de Uitzicht
objecten hebben een aantal eigenschappen gemeen, die u kunt gebruiken om de tekst, kleuren, spatiëring, hoogte, breedte, enz. in te stellen. U hoeft nu alleen de GetMainPage
methode in de App
klasse om een nieuw exemplaar van de. te retourneren Voorbeeld pagina
klasse, en alsjeblieft.
Niemand heeft me ooit beschuldigd een ontwerper te zijn, maar het is zo eenvoudig om basispagina's in code te maken.
Als u liever het uiterlijk van uw toepassing wilt scheiden van de logica en implementatie, dan is XAML misschien wel de juiste keuze. Met XAML kunt u de volledige lay-out van uw toepassing maken in een gespecialiseerd XML-formaat dat Xamarin kan vertalen naar de pagina's, lay-outs, weergaven en cellen en deze aan de gebruiker kan weergeven. Als u nog nooit XAML hebt gebruikt, is het misschien even wennen. Maar als je het eenmaal onder de knie hebt, kan het best heel leuk zijn.
Als u XAML in combinatie met Xamarin.Forms wilt gebruiken, moet u uw project maken met behulp van de Lege app (Xamarin.Forms Portable) sjabloon zodat alle Xamarin.Forms-code kan worden gescheiden in zijn eigen dll.
In het codevoorbeeld van het vorige gedeelte hebt u een heel eenvoudige gemaakt Inhoudsopgave
klasse in code. Om precies hetzelfde te maken Inhoudsopgave
met XAML, klik met de rechtermuisknop op het PCL-project en selecteer Voeg toe> Nieuw item. Van de Voeg een nieuw item toe dialoogvenster, selecteert u de Formulieren Xaml-pagina sjabloon en vervang de standaardinhoud door het volgende:
Als u uw toepassing uitvoert, ziet u hetzelfde scherm als in het codevoorbeeld. De Pagina
, lay-out
, en Uitzicht
typ map naar XML-elementen en de eigenschappen zijn de elementattributen. U bent vrij om beide opties te gebruiken om volledig aanpasbare, platformonafhankelijke gebruikersinterfaces te maken.
U kunt apps maken waar u de Uitzicht
objecten voor je Pagina
objecten en expliciet hun eigenschappen instellen, maar dat wordt snel omslachtig. Wanneer u expliciet eigenschappen in uw XAML-code instelt, kunt u die XAML niet meer opnieuw gebruiken Pagina
voor iets anders. Met andere woorden, u moet nieuwe XAML-pagina's maken voor elke variatie die u nodig hebt. Wie heeft daar tijd voor?
Zou het niet mooi zijn als u herbruikbare XAML-pagina's zonder aangepaste gebruikersinterfacekode zou kunnen maken en alles logisch gescheiden zou houden? Natuurlijk. Welkom bij MVVM.
Model-View-ViewModeIk ben een architecturaal patroon dat is gemaakt met XAML in gedachten. In de kern deelt het het basisconcept van andere architecturale patronen zoals MVP en MVC. Het is ontworpen om gegevens, de modellaag, van de presentatie, de weergavelaag, te scheiden. Het kanaal tussen de twee is de ViewModel. Het weergavemodel is een klasse die de communicatie tussen het model en de weergave lagen vergemakkelijkt via een mechanisme dat bekend staat als Dataverbinding. Gegevensbinding vormt de kern van het MVVM-patroon en wordt gedaan via XAML zelf. Laten we een voorbeeld bekijken.
Begin met het maken van een nieuwe Xamarin.Forms-toepassing door de. Te selecteren Lege app (Xamarin.Forms Portable) projectsjabloon en het de naam geven van MyRecipeBox.
Zoals je waarschijnlijk al geraden hebt, zal dit de basis zijn voor een eenvoudige app die recepten kan opslaan. Laten we beginnen met het maken van een basismodel van de app, een recept.
In de MyRecipeBox project, maak een nieuwe map en noem die modellen. Dit is geen vereiste, het voegt gewoon wat organisatie toe aan het project dat altijd helpt als het groter wordt. In de modellen map, voeg een nieuwe klasse toe en geef deze een naam Recept
. Vervang de standaardimplementatie door het volgende:
public class Recept public string Name get; vast te stellen; public string Description get; vast te stellen; public TimeSpan PrepTime get; vast te stellen; public TimeSpan CookingTime get; vast te stellen; openbare lijstRoutebeschrijving krijg; vast te stellen;
Nu u een basismodelklasse hebt, kunt u er een weergavemodel voor maken. Beschouw een weergavemodel als een klasse die de onderdelen van een model bevat die op een scherm moeten worden getoond en waarmee interactie mogelijk is. Om het simpel te houden, gaan we ons concentreren op de top vier eigenschappen.
Maak een nieuwe map in de MyRecipeBox project en noem het ViewModels. In de ViewModels map, maak een nieuwe klasse aan en noem deze RecipeViewModel
. Bij het adopteren van het MVVM-patroon in .NET, worden ViewModels meestal gekenmerkt door het feit dat ze het INotifyPropertyChanged
interface. Deze interface is wat wordt gebruikt om andere delen van de code toe te staan om zich te abonneren op gebeurtenissen en gegevensbinding mogelijk te maken. Vervang de standaardimplementatie van de RecipeViewModel
les met het volgende:
public class RecipeViewModel: INotifyPropertyChanged private Recept _recept; public event PropertyChangedEventHandler PropertyChanged; public RecipeViewModel (Recept recept) _recipe = recept; Richtingen = nieuwe ObservableCollection(_Recipe.Directions); public ObservableCollection Routebeschrijving krijg; vast te stellen; public string Name krijg return _recipe! = null? _recipe.Name: null; set if (_recipe! = null) _recipe.Name = waarde; if (PropertyChanged! = null) PropertyChanged (this, new PropertyChangedEventArgs ("Name")); openbare tekenreeks Beschrijving krijg return _recipe! = null? _recipe.Description: null; set if (_recipe! = null) _recipe.Description = waarde; if (PropertyChanged! = null) PropertyChanged (this, new PropertyChangedEventArgs ("Description")); openbare string PrepTime krijg return _recipe! = null? _recipe.PrepTime.ToString (): "Geen"; set if (_recipe! = null) _recipe.PrepTime = TimeSpan.Parse (waarde); if (PropertyChanged! = null) PropertyChanged (this, new PropertyChangedEventArgs ("PrepTime")); openbare string CookingTime krijg return _recipe! = null? _recipe.CookingTime.ToString (): "Geen"; set if (_recipe! = null) _recipe.CookingTime = TimeSpan.Parse (waarde); if (PropertyChanged! = null) PropertyChanged (this, new PropertyChangedEventArgs ("CookingTime"));
Je hebt misschien gemerkt dat de RecipeViewModel
implementeert de INotifyPropertyChanged
interface. Als u dieper ingaat op deze interface, ziet u dat deze één eigenschap bevat die moet worden geïmplementeerd.
openbare interface INotifyPropertyChanged event PropertyChangedEventHandler PropertyChanged;
De RecipleViewModel
klasse neemt een instantie van de Recept
klasse en stelt vervolgens slechts vier van zijn eigenschappen bloot. De getters die aan deze eigenschappen zijn gekoppeld, geven eenvoudig de gegevens in de Recept
instantie zelf. De setters aan de andere kant controleren om te zien of PropertyChanged
is niet nul
. PropertyChanged
zal zijn nul
als er geen abonnees zijn voor deze gebeurtenis. In dat geval gebeurt er niets. Als PropertyChanged
is niet nul
, dan wordt de gebeurtenis opgeroepen en ontvangt elke abonnee van de gebeurtenis de informatie dat dit weergavemodel is gewijzigd.
In het MVVM-patroon is de abonnee van deze gebeurtenissen meestal de weergave die door de XAML wordt beschreven, waardoor de gebruikersinterface kan worden bijgewerkt als de onderliggende modellen zijn gewijzigd.
Het is tijd om een pagina te maken die de gebruiker de receptgegevens toont en gebruikmaakt van databinding om de gebruikersinterface bij te werken. Begin met het maken van een Keer bekeken map in de MyRecipeBox project. In de Keer bekeken map, voeg een nieuwe toe Formulieren Xaml-pagina en noem het RecipeSummaryPage
.
Vervang de standaard XAML in het bestand door het volgende:
Zoals u kunt zien, wordt de binding gemaakt door een opgemaakte tekst te plaatsen waar u de gebonden gegevens wilt laten verschijnen. De syntaxis om dat te bereiken is "Binding xxxxx"
, waar xxxxx
is de naam van de eigenschap waaraan u wilt binden. Ten slotte vraagt u zich misschien af hoe u het weergavemodel dat u hebt gemaakt, aan deze weergave kunt koppelen.
Als u op het kleine pijltje naast de RecipeSummaryPage.xaml bestand, zou u een ander bestand moeten zien verschijnen, RecipleSummaryPage.xaml.cs. Dit is de code achter het bestand met de C # -code om deze pagina uit te voeren. U moet de constructor van deze klasse wijzigen om er als volgt uit te zien:
public RecipeSummaryPage (ReceptViewModel recipeViewModel) InitializeComponent (); this.BindingContext = recipeViewModel;
De BindingContext
eigenschap is waar u het weergavemodel moet toewijzen om de eerder genoemde binding te maken. Om dat te doen, geef je een exemplaar van je door RecipeViewModel
in de constructor.
Om de vruchten van onze arbeid op het scherm te zien verschijnen, moet u een kleine wijziging aanbrengen om dit te laten werken. In de App.cs bestand, in de MyRecipeBox project, update de GetMainPage
methode zoals hieronder getoond.
public static Pagina GetMainPage () var recipe = new Recipe Name = "Toast", Description = "Het is geroosterd, maakt u een grapje?", PrepTime = nieuw TimeSpan (0, 0, 15), CookingTime = nieuw TimeSpan (0, 2, 0), routebeschrijving = nieuwe lijst"Pak brood", "Zet brood in broodrooster", "Eet toast"; retourneer nieuwe RecipeSummaryPage (nieuw recept Receptmodel (recept));
Het resultaat zou moeten lijken op de volgende schermafbeeldingen.
In de volgende en laatste stap maken we een lijst met Recept
objecten die de gebruiker kan aanklikken om ze naar een detailpagina te brengen. Laten we beginnen met het maken van een nieuw weergavemodel met een lijst met Recept
voorwerpen. Voeg een nieuwe klasse toe aan de ViewModels map en noem deze RecipeListViewModel
. De implementatie ziet er als volgt uit:
public class RecipeListViewModel public ObservableCollectionRecepten krijg; vast te stellen; public RecipeListViewModel () Recipes = new ObservableCollection (); Recipes.Add (new Recipe Name = "Toast", Description = "Maak maar een grapje? Het is toast.", CookingTime = new TimeSpan (0, 2, 0), PrepTime = new TimeSpan (0, 0, 15), Routebeschrijving = nieuwe lijst "Haal brood op", "Zet broodrooster in", "Eat Toast"); Recipes.Add (new Recipe Name = "Cereal", Description = "Weet je, het ontbijt spul.", CookingTime = TimeSpan.Zero, PrepTime = new TimeSpan (0, 1, 0), Directions = new Lijst "Doe de granen in de kom", "Doe de melk in de kom", "Doe de lepel in de kom", "Doe de lepel in de mond"); Recipes.Add (new Recipe Name = "Sandwich", Description = "Bread and stuff. YUM!", CookingTime = TimeSpan.Zero, PrepTime = new TimeSpan (0, 5, 0), Directions = new Lijst "Koop 2 sneetjes brood", "Leg kaas tussen pauze-segmenten", "Leg ham tussen pauze-plakjes", "Geniet");
Je hebt misschien gemerkt dat we de recepten hard codeerden in de RecipeListViewModel
klasse. In een echte toepassing zouden de recepten worden opgehaald van een webservice of een database.
Maak een nieuwe pagina om de lijst met recepten weer te geven. In de Keer bekeken map, maak een nieuwe aan Form Xaml-pagina en noem deze RecipleListPage
. Vervang de inhoud door het volgende:
Deze XAML lijkt veel op het vorige voorbeeld. Deze keer hebt u echter alleen een lijstweergave op de pagina. Bij gebruik van databinding in a Lijstweergave
, je moet een beetje dieper graven om de daadwerkelijke binding te doen. Eerst bindt u de volledige lijst aan de ItemsSource
eigendom van deLijstweergave
en je moet dan de Sjabloon
en DataTemplate
van de Lijstweergave
een ... zijn TextCell
en bind dat TextCell
naar de individuele eigendom van de Recept
bijvoorbeeld dat u wilt weergeven. Dit is wat de receptnamen op het scherm weergeeft.
Je kunt ook zien dat er een is Naam
geassocieerd met de Lijstweergave
, recipeList
, wat een beetje later van pas zal komen, evenals een gebeurtenishandler. In dit geval, wanneer een gebruiker op een item in de Lijstweergave
, de ItemTapped
evenement is ontslagen. U bent nu geabonneerd op die gebeurtenis en zult een methode met de naam gebruiken OnItemSelected
om het aan te pakken.
In de volgende stap moeten we wat bedrading uitvoeren in de RecipeListPage.xaml.cs bestand om deBindingContext
van onze nieuwe pagina en implementeer de OnItemSelected
gebeurtenishandler.
openbare gedeeltelijke klasse RecipeListPage public RecipeListPage () InitializeComponent (); this.BindingContext = new RecipeListViewModel (); public void OnItemSelected (object afzender, ItemTappedEventArgs args) var recipe = args.Item as Recipe; if (recipe == null) retour; Navigation.PushAsync (nieuwe RecipeSummaryPage (nieuw recept Receptmodel (recept))); // Reset het geselecteerde item recipeList.SelectedItem = null;
De BindingContext
eigenschap zal eenvoudig worden ingesteld op een nieuw exemplaar van de RecipleListViewModel
die je eerder hebt gemaakt. De gebeurtenishandlermethode is een beetje anders. Eerst moet je controleren of het geselecteerde item een recept is, wat wordt bereikt in de volgende regels:
var recipe = args.Item as Recipe; if (recipe == null) retour;
Als het geselecteerde item een is Recept
object, gebruik dan de Navigatie
eigenschap om een nieuw exemplaar van de. toe te voegen RecipleSummaryPage
naar de stroom NavigationView
. Ten slotte moet u ervoor zorgen dat er momenteel geen items in de lijst zijn geselecteerd.
Navigation.PushAsync (nieuwe RecipeSummaryPage (nieuw recept Receptmodel (recept))); // Reset het geselecteerde item recipeList.SelectedItem = null;
Toegang tot de Lijstweergave
wordt gedaan via de Naam
dat was eerder toegewezen. U kunt toegang krijgen tot elke Uitzicht
op de pagina door een Naam
naar deUitzicht
en ernaar te verwijzen met naam in de code.
De laatste verandering die we moeten aanbrengen, is het updaten van GetMainPage
methode in de App.cs het dossier. zoals hieronder getoond:
public static Pagina GetMainPage () retourneer nieuwe NavigationPage (nieuwe RecipeListPage ());
U retourneert een nieuw exemplaar van de NavigationPage
class als uw hoofdpagina en stel de hoofdpagina in op een nieuw exemplaar van de RecipleListPage
klasse. Nu alles is aangesloten, kunt u uw app op alle drie de platforms uitvoeren en zoiets als het volgende zien:
Als u op een van de rijen in de lijst tikt, gaat u naar de bijbehorende receptenoverzichtspagina zoals u eerder hebt gezien.
U hebt nu de verschillende opties gezien om uw toepassing op te stellen met behulp van Xamarin.Forms. U moet zich op uw gemak voelen bij het maken van basistoepassingen die op de grote mobiele platforms kunnen worden uitgevoerd met behulp van een enkele codebasis voor zowel de bedrijfslogica als de gebruikersinterface van de toepassing. Als u enige tijd met Xamarin.Forms hebt gewerkt, leert u de gebruikersinterface van de toepassing aanpassen en nieuwe besturingselementen toevoegen. Maar dat is voor een andere dag.
Als je meer wilt weten over Xamarin, bekijk dan onze cursus Bouwen met meerdere platform-apps met C # in Xamarin.
In de cursus leert u hoe u een platformonafhankelijke toepassing kunt maken op basis van één code die op drie duidelijk verschillende platforms wordt uitgevoerd: iOS, Android en Windows Phone 8. Denkt u dat dit niet mogelijk is? Binnen een korte tijd zul je het zelf doen. Laten we aan de slag gaan.
Je kunt het meteen nemen met een helemaal gratis 14 dagen proef van een Tuts + abonnement. Bekijk onze abonnementsopties om aan de slag te gaan of, als u alleen geïnteresseerd bent in deze cursus, kunt u deze afzonderlijk kopen voor $ 15! Hier is een voorbeeld om mee te beginnen: