Wpf e Xamarin.Forms App Lifecycle
Xamarin.Forms prende molte linee guida di progettazione dai framework basati su XAML che sono arrivati prima, in particolare WPF. Tuttavia, in altri modi devia in modo significativo che può essere un punto permanente per le persone che tentano di eseguire la migrazione. Questo documento prova a identificare alcuni di questi problemi e fornisce indicazioni dove possibile collegare le conoscenze WPF a Xamarin.Forms.
Ciclo di vita dell'app
Il ciclo di vita dell'applicazione tra WPF e Xamarin.Forms è simile. Entrambi iniziano nel codice esterno (piattaforma) e avviano l'interfaccia utente tramite una chiamata al metodo. La differenza è che Xamarin.Forms viene sempre avviato in un assembly specifico della piattaforma che quindi inizializza e crea l'interfaccia utente per l'app.
WPF
Main method > App > MainWindow
Nota
Il Main
metodo è, per impostazione predefinita, generato automaticamente e non visibile nel codice.
Xamarin.Forms
- iOS :
Main method > AppDelegate > App > ContentPage
- Android :
MainActivity > App > ContentPage
- UWP :
Main method > App(UWP) > MainPage(UWP) > App > ContentPage
Classe App
Wpf e Xamarin.Forms hanno una Application
classe creata come singleton. Nella maggior parte dei casi, le app derivano da questa classe per fornire un'applicazione personalizzata, anche se questa operazione non è strettamente necessaria in WPF. Entrambi espongono una Application.Current
proprietà per individuare il singleton creato.
Proprietà globali e persistenza
WPF e Xamarin.Forms hanno un Application.Properties
dizionario disponibile in cui è possibile archiviare oggetti globali a livello di app accessibili ovunque nell'applicazione. La differenza principale è che Xamarin.Forms rende persistenti tutti i tipi primitivi archiviati nella raccolta quando l'app viene sospesa e ricaricarla quando viene riavviata. WPF non supporta automaticamente tale comportamento, ma la maggior parte degli sviluppatori si basava sull'archiviazione isolata o utilizzava il supporto predefinito Settings
.
Definizione di pagine e struttura ad albero visuale
WPF usa come Window
elemento radice per qualsiasi elemento visivo di primo livello. Definisce un HWND nel mondo Windows per visualizzare informazioni. È possibile creare e visualizzare tutte le finestre contemporaneamente desiderate in WPF.
In Xamarin.Forms, l'oggetto visivo di primo livello è sempre definito dalla piattaforma, ad esempio in iOS, è un UIWindow
oggetto . Xamarin.Forms esegue il rendering del contenuto in queste rappresentazioni della piattaforma nativa usando una Page
classe . Ogni Page
oggetto in Xamarin.Forms rappresenta una "pagina" univoca nell'applicazione, in cui solo uno è visibile alla volta.
Sia i file WPF Window
che Xamarin.Forms Page
includono una Title
proprietà per influenzare il titolo visualizzato e hanno entrambe una Icon
proprietà per visualizzare un'icona specifica per la pagina (si noti che il titolo e l'icona non sono sempre visibili in Xamarin.Forms). Inoltre, è possibile modificare le proprietà visive comuni in entrambi, ad esempio il colore di sfondo o l'immagine.
È tecnicamente possibile eseguire il rendering in due visualizzazioni della piattaforma separate (ad esempio, definire due UIWindow
oggetti e fare in modo che il secondo esegua il rendering in una visualizzazione esterna o AirPlay), richiede codice specifico della piattaforma per farlo e non è una funzionalità direttamente supportata di Xamarin.Forms.
Visualizzazioni
La gerarchia visiva per entrambi i framework è simile. WPF è un po' più profondo a causa del supporto per i documenti WYSIWYG.
WPF
DependencyObject - base class for all bindable things
Visual - rendering mechanics
UIElement - common events + interactions
FrameworkElement - adds layout
Shape - 2D graphics
Control - interactive controls
Xamarin.Forms
BindableObject - base class for all bindable things
Element - basic parent/child support + resources + effects
VisualElement - adds visual rendering properties (color, fonts, transforms, etc.)
View - layout + gesture support
Ciclo di vita della visualizzazione
Xamarin.Forms è orientato principalmente agli scenari per dispositivi mobili. Di conseguenza, le applicazioni vengono attivate, sospese e riattivate quando l'utente interagisce con loro. Questo comportamento è simile a quando si fa clic da Window
in un'applicazione WPF e sono disponibili un set di metodi e gli eventi corrispondenti che è possibile eseguire l'override o l'hook in per monitorare questo comportamento.
Scopo | WPF, metodo | Metodo Xamarin.Forms |
---|---|---|
Attivazione iniziale | ctor + Window.OnLoaded | ctor + Page.OnStart |
Visualizzati | Window.IsVisibleChanged | Page.Appearing |
Nascosta | Window.IsVisibleChanged | Page.Disappearing |
Sospensione/Perdita dello stato attivo | Window.OnDeactivated | Page.OnSleep |
Attivato/Messa a fuoco | Window.OnActivated | Page.OnResume |
Chiusa | Window.OnClosing + Window.OnClosed | n/d |
Entrambi supportano la visualizzazione o la visualizzazione dei controlli figlio, in WPF è una proprietà IsVisible
tri-state (visibile, nascosta e compressa). In Xamarin.Forms è semplicemente visibile o nascosta tramite la IsVisible
proprietà .
Layout
Il layout di pagina si verifica nello stesso passaggio (Misura/Disposizione) che si verifica in WPF. È possibile eseguire l'hook nel layout di pagina eseguendo l'override dei metodi seguenti nella classe Xamarin.Forms Page
:
metodo | Scopo |
---|---|
OnChildMeasureInvalidated | Le dimensioni preferite di un figlio sono cambiate. |
OnSizeAllocated | Alla pagina è stata assegnata una larghezza/altezza. |
Evento LayoutChanged | Layout/dimensioni della pagina modificata. |
Non esiste alcun evento di layout globale che viene chiamato oggi, né è presente un evento globale CompositionTarget.Rendering
come trovato in WPF.
Proprietà di layout comuni
WPF e Xamarin.Forms supportano Margin
entrambi per controllare la spaziatura intorno a un elemento e Padding
per controllare la spaziatura all'interno di un elemento. Inoltre, la maggior parte delle viste di layout di Xamarin.Forms ha proprietà per controllare la spaziatura ,ad esempio riga o colonna.
Inoltre, la maggior parte degli elementi ha proprietà per influenzare il modo in cui vengono posizionati nel contenitore padre:
WPF | Xamarin.Forms | Scopo |
---|---|---|
HorizontalAlignment | HorizontalOptions | Opzioni a sinistra/al centro/a destra/estensione |
VerticalAlignment | VerticalOptions | Opzioni Top/Center/Bottom/Stretch |
Nota
L'interpretazione effettiva di queste proprietà dipende dal contenitore padre.
Visualizzazioni layout
WPF e Xamarin.Forms usano entrambi i controlli di layout per posizionare gli elementi figlio. Nella maggior parte dei casi, questi sono molto vicini tra loro in termini di funzionalità.
WPF | Xamarin.Forms | Stile layout |
---|---|---|
StackPanel | StackLayout | Stacking infinito da sinistra a destra o dall'alto verso il basso |
Griglia | Griglia | Formato tabulare (righe e colonne) |
DockPanel | n/d | Ancorare ai bordi della finestra |
Canvas | AbsoluteLayout | Posizionamento pixel/coordinata |
WrapPanel | n/d | Stack di wrapping |
n/d | RelativeLayout | Posizionamento relativo basato su regole |
Nota
Xamarin.Forms non supporta un oggetto GridSplitter
.
Entrambe le piattaforme usano proprietà associate per ottimizzare gli elementi figlio.
Rendering
I meccanismi di rendering per WPF e Xamarin.Forms sono radicalmente diversi. In WPF i controlli creati direttamente eseguono il rendering diretto del contenuto in pixel sullo schermo. WPF gestisce due grafici a oggetti (alberi) per rappresentare questo aspetto: l'alberologico rappresenta i controlli definiti nel codice o XAML e la struttura ad albero visuale rappresenta il rendering effettivo che si verifica sullo schermo che viene eseguito direttamente dall'elemento visivo (tramite un metodo di disegno virtuale) o tramite un codice XAML ControlTemplate
che può essere sostituito o personalizzato. In genere, la struttura ad albero visuale è più complessa perché include elementi quali bordi intorno a controlli, etichette per il contenuto implicito e così via. WPF include un set di API (LogicalTreeHelper
e VisualTreeHelper
) per esaminare questi due oggetti grafici.
In Xamarin.Forms i controlli definiti in un Page
sono semplicemente oggetti dati semplici. Sono simili alla rappresentazione ad albero logico, ma non eseguono mai il rendering del contenuto autonomamente. Sono invece il modello di dati che influenza il rendering degli elementi. Il rendering effettivo viene eseguito da un set separato di renderer visivi di cui viene eseguito il mapping a ogni tipo di controllo. Questi renderer vengono registrati in ognuno dei progetti specifici della piattaforma da assembly Xamarin.Forms specifici della piattaforma. È possibile visualizzare un elenco qui. Oltre a sostituire o estendere il renderer, Xamarin.Forms include anche il supporto per Effects che può essere usato per influenzare il rendering nativo in base alla piattaforma.
Albero logico/visivo
Non esiste alcuna API esposta per esaminare l'albero logico in Xamarin.Forms, ma è possibile usare Reflection per ottenere le stesse informazioni. Ecco, ad esempio, un metodo che può enumerare elementi figlio logici con reflection.
Grafica
Xamarin.Forms include un sistema grafico per disegnare primitive, denominate Forme. Per altre informazioni sulle forme, vedere Forme Xamarin.Forms. Inoltre, è possibile includere librerie di terze parti come SkiaSharp per ottenere il disegno 2D multipiattaforma.
Risorse
WPF e Xamarin.Forms hanno entrambi il concetto di risorse e dizionari risorse. È possibile inserire qualsiasi tipo di oggetto in un ResourceDictionary
oggetto con una chiave e quindi cercarlo per {StaticResource}
individuare gli elementi che non cambieranno o {DynamicResource}
per gli elementi che possono cambiare nel dizionario in fase di esecuzione. L'utilizzo e la meccanica sono uguali con una differenza: Xamarin.Forms richiede di definire l'oggetto ResourceDictionary
da assegnare alla Resources
proprietà, mentre WPF ne crea uno e lo assegna automaticamente.
Ad esempio, vedere la definizione seguente:
WPF
<Window.Resources>
<Color x:Key="redColor">#ff0000</Color>
...
</Window.Resources>
Xamarin.Forms
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="redColor">#ff0000</Color>
...
</ResourceDictionary>
</ContentPage.Resources>
Se non si definisce ResourceDictionary
, viene generato un errore di runtime.
Stili
Gli stili sono inoltre completamente supportati in Xamarin.Forms e possono essere usati per temiare gli elementi di Xamarin.Forms che costituiscono l'interfaccia utente. Supportano trigger (proprietà, eventi e dati), ereditarietà tramite BasedOn
le ricerche di risorse e per i valori. Gli stili vengono applicati agli elementi in modo esplicito tramite la Style
proprietà o in modo implicito non fornendo una chiave di risorsa, proprio come WPF.
Stili di dispositivo
WPF dispone di un set di proprietà predefinite (archiviate come valori statici in un set di classi statiche, SystemColors
ad esempio ) che determinano colori di sistema, tipi di carattere e metriche sotto forma di valori e chiavi di risorsa. Xamarin.Forms è simile, ma definisce un set di stili di dispositivo per rappresentare gli stessi elementi. Questi stili vengono forniti dal framework e impostati su valori basati sull'ambiente di runtime ,ad esempio l'accessibilità.
WPF
<Label Text="Title" Foreground="{DynamicResource {x:Static SystemColors.DesktopBrushKey}}" />
Xamarin.Forms
<Label Text="Title" Style="{DynamicResource TitleStyle}" />