Migrazione a Windows App SDK dell'app di esempio PhotoLab UWP (C#)
Questo argomento è un case study sull'acquisizione dell' app di esempio PhotoLab UWP di C# e sulla sua migrazione a Windows App SDK.
Iniziare clonando il repository dell'app di esempio UWP e aprendo la soluzione in Visual Studio.
Importante
Per considerazioni e strategie per affrontare il processo di migrazione e su come configurare l'ambiente di sviluppo per la migrazione, vedere Strategia di migrazione globale. È particolarmente importante vedere Cosa è supportato durante la conversione dalla piattaforma UWP a WinUI 3 in modo da garantire che tutte le funzionalità necessarie per l'app siano supportate prima di tentare la migrazione.
Installare gli strumenti per Windows App SDK
Per configurare il computer di sviluppo, consultare Installare gli strumenti per Windows App SDK.
Importante
Sono disponibili argomenti sulle note di rilascio insieme all'argomento Canali di rilascio di Windows App SDK. Sono disponibili note sulla versione per ogni canale. Assicurarsi di controllare eventuali limitazioni e problemi noti nelle note di rilascio, perché potrebbero influire sui risultati del seguito di questo case study e/o dell'esecuzione dell'app migrata.
Crea un nuovo progetto
In Visual Studio, creare un nuovo progetto C# dal modello di progetto App vuota, in pacchetto (WinUI 3 in Desktop). Assegnare al progetto il nome PhotoLabWinUI, deselezionare Inserisci soluzione e progetto nella stessa directory. Puoi specificare come destinazione la versione più recente (non l'anteprima) del sistema operativo client.
Nota
Si farà riferimento alla versione UWP del progetto di esempio (quella clonata dal suo repository) come soluzione/progetto di origine. Si farà riferimento alla versione Windows App SDK come soluzione progetto di destinazione.
Ordine in cui verrà eseguita la migrazione del codice
MainPage è un elemento importante e significativo dell'app. Ma se iniziassimo con la migrazione di quella versione, ci accorgeremmo presto che MainPage ha una dipendenza dalla vista DetailPage; e che DetailPage ha una dipendenza dal modello ImageFileInfo. Per questa procedura dettagliata verrà quindi adottato questo approccio.
- Si inizierà copiando i file di asset.
- Si eseguirà quindi la migrazione del modello ImageFileInfo.
- Successivamente eseguiremo la migrazione della classe App (perché richiede modifiche da cui dipenderanno DetailPage, MainPage e, and LoadedImageBrush).
- Si eseguirà quindi la migrazione della classe LoadedImageBrush.
- Si inizierà quindi a eseguire la migrazione delle visualizzazioni, a partire prima da DetailPage.
- E alla fine si eseguirà la migrazione della visualizzazione MainPage .
Copiare i file di asset
Nel progetto di destinazione in Visual Studio, in Esplora soluzioni, fare clic con il pulsante destro del mouse sulla cartella Assets e aggiungere una nuova cartella denominata
Samples
.Nel clone del progetto di origine, in Esplora file, trovare la cartella Windows-appsample-photo-editor>PhotoEditor>Assets. Nella cartella sono disponibili sette file di asset, insieme a una sottocartella denominata Samples contenente esempi di immagini. Selezionare i sette file di asset e la sottocartella Samples e copiarli negli Appunti.
Sempre in Esplora file, trovare la cartella corrispondente nel progetto di destinazione creato. Il percorso della cartella è PhotoEditor>PhotoEditor>Assets. Incollare nella cartella i file di asset appena copiati e accettare la richiesta di sostituire i file già esistenti nella destinazione.
Nel progetto di destinazione in Visual Studio, in Esplora soluzioni, con la cartella Assets espansa, verrà visualizzato nella cartella Samples il contenuto della sottocartella Samples (incollato). È possibile posizionare il puntatore del mouse sui file di asset. Verrà visualizzata un'anteprima per ognuna, confermando di aver sostituito o aggiunto correttamente i file di asset.
Migrazione del modello ImageFileInfo
ImageFileInfo è un modello (nel senso di modelli, visualizzazioni e modelli di visualizzazione) che rappresenta un file di immagine, come una foto.
Copiare i file del codice sorgente ImageFileInfo
Nel clone del progetto di origine, in Esplora file, trovare la cartella Windows-appsample-photo-editor>PhotoEditor. Nella cartella si troverà il file del codice sorgente
ImageFileInfo.cs
, che contiene l'implementazione di ImageFileInfo. Selezionare il file e copiarlo negli Appunti.In Visual Studio, fare clic con il pulsante destro del mouse sul nodo del progetto e fare clic su Apri cartella in Esplora file. Verrà aperta la cartella del progetto di destinazione in Esplora file. Incollare nella cartella il file appena copiato.
Migrazione del codice sorgente ImageFileInfo
- Eseguire le operazioni di ricerca/sostituzione seguenti (distinzione tra maiuscole/minuscole e parola intera) nel file
ImageFileInfo.cs
appena incollato.
namespace PhotoLab
=>namespace PhotoLabWinUI
Windows.UI.Xaml
=>Microsoft.UI.Xaml
Windows.UI.Xaml è lo spazio dei nomi per XAML UWP; Microsoft.UI.Xaml è lo spazio dei nomi per XAML WinUI.
Nota
L'argomento Mapping delle API UWP a Windows App SDK fornisce un mapping delle API UWP ai relativi equivalenti Windows App SDK. La modifica apportata in precedenza è un esempio di modifica del nome dello spazio dei nomi necessaria durante il processo di migrazione.
- A questo punto, verificare che sia possibile compilare la soluzione di destinazione (ma non eseguirla ancora).
Migrazione della classe App
- Dal progetto di origine, nell'elemento
<Application.Resources>
inApp.xaml
, trovare le quattro righe seguenti. Copiarle e incollarle nel progetto di destinazione.
<SolidColorBrush x:Key="RatingControlSelectedForeground" Color="White"/>
<!-- Window width adaptive breakpoints. -->
<x:Double x:Key="MinWindowBreakpoint">0</x:Double>
<x:Double x:Key="MediumWindowBreakpoint">641</x:Double>
<x:Double x:Key="LargeWindowBreakpoint">1008</x:Double>
Nota
Dato che il progetto di destinazione userà uno spostamento diverso (e più semplice) dal progetto di origine, non è necessario copiare altro codice dal App.xaml.cs
del progetto di origine.
- Nel progetto di destinazione, App memorizza l'oggetto finestra principale nel suo campo privato m_window. Più avanti nel processo di migrazione (quando si eseguirà la migrazione dell'uso del progetto di origine di Window.Current), sarà utile se il campo privato è invece una proprietà statica pubblica. Sostituire quindi il campo m_window con una proprietà Window e modificare i riferimenti a m_window, come illustrato di seguito.
// App.xaml.cs
public partial class App : Application
{
...
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
Window = new MainWindow();
Window.Activate();
}
public static MainWindow Window { get; private set; }
}
- Più avanti nel processo di migrazione (quando eseguiremo il codice che visualizza un FileSavePicker), sarà utile se App espone l'handle della finestra principale (HWND). Aggiungere quindi una proprietà WindowHandle e inizializzarla nel metodo OnLaunched, come illustrato di seguito.
// App.xaml.cs
public partial class App : Application
{
...
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
Window = new MainWindow();
Window.Activate();
WindowHandle = WinRT.Interop.WindowNative.GetWindowHandle(Window);
}
public static IntPtr WindowHandle { get; private set; }
}
Migrazione del modello LoadedImageBrush
LoadedImageBrush è una specializzazione di XamlCompositionBrushBase. L'app di esempio PhotoLab usa la classe LoadedImageBrush per applicare effetti alle foto.
Fare riferimento al pacchetto NuGet Win2D
Per supportare il codice in LoadedImageBrush, il progetto di origine ha una dipendenza da Win2D. Sarà quindi necessaria una dipendenza da Win2D anche nel progetto di destinazione.
Nella soluzione di destinazione in Visual Studio, fare clic su Strumenti>Gestione pacchetti NuGet>Gestisci pacchetti NuGet per la soluzione...>Sfoglia e digita o incolla Microsoft.Graphics.Win2D. Selezionare l'elemento corretto nei risultati della ricerca, controllare il progetto PhotoLabWinUI e fare clic su Installa per installare il pacchetto nel progetto.
Copiare i file del codice sorgente LoadedImageBrush
Copiare LoadedImageBrush.cs
dal progetto di origine a quello di destinazione nello stesso modo in cui è stato copiato ImageFileInfo.cs
.
Migrazione del codice sorgente LoadedImageBrush
- Eseguire le operazioni di ricerca/sostituzione seguenti (distinzione tra maiuscole/minuscole e parola intera) nel file
LoadedImageBrush.cs
appena incollato.
namespace PhotoLab
=>namespace PhotoLabWinUI
Windows.UI.Composition
=>Microsoft.UI.Composition
Windows.UI.Xaml
=>Microsoft.UI.Xaml
Window.Current.Compositor
=>App.Window.Compositor
(vedere Modificare Windows.UI.Xaml.Window.Current in App.Window)
- A questo punto, verificare che sia possibile compilare la soluzione di destinazione (ma non eseguirla ancora).
Migrazione della visualizzazione DetailPage
DetailPage è la classe che rappresenta la pagina dell'editor di foto, in cui gli effetti Win2D vengono attivati, impostati e concatenati. Si arriva alla pagina dell'editor di foto selezionando un'anteprima della foto in MainPage. DetailPage è un modello (nel senso di modelli, visualizzazioni e modelli di visualizzazione).
Copiare i file del codice sorgente DetailPage
Copiare DetailPage.xaml
e DetailPage.xaml.cs
dal progetto di origine a quello di destinazione nello stesso modo in cui sono stati copiati i file nei passaggi precedenti.
Migrazione del codice sorgente DetailPage
- Eseguire le operazioni di ricerca/sostituzione seguenti (distinzione tra maiuscole/minuscole e parola intera) nel file
DetailPage.xaml
appena incollato.
PhotoLab
=>PhotoLabWinUI
- Eseguire le operazioni di ricerca/sostituzione seguenti (distinzione tra maiuscole/minuscole e parola intera) nel file
DetailPage.xaml.cs
appena incollato.
namespace PhotoLab
=>namespace PhotoLabWinUI
Windows.UI.Colors
=>Microsoft.UI.Colors
Windows.UI.Xaml
=>Microsoft.UI.Xaml
- Per il passaggio successivo, verrà apportata la modifica illustrata in ContentDialog e Popup. Quindi, sempre in
DetailPage.xaml.cs
, nel metodo ShowSaveDialog, immediatamente prima della rigaContentDialogResult result = await saveDialog.ShowAsync();
, aggiungere questo codice.
if (Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
{
saveDialog.XamlRoot = this.Content.XamlRoot;
}
- Sempre in
DetailPage.xaml.cs
, nel metodo OnNavigatedTo, eliminare le due righe di codice seguenti. Solo quelle due righe; più avanti in questo case study verrà reintrodotta la funzionalità del pulsante Indietro appena rimossa.
...
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
AppViewBackButtonVisibility.Visible;
...
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
AppViewBackButtonVisibility.Collapsed;
...
- Per questo passaggio, verrà apportata la modifica illustrata in MessageDialog e selettori. Sempre in
DetailPage.xaml.cs
, nel metodo ExportImage, immediatamente prima della rigavar outputFile = await fileSavePicker.PickSaveFileAsync();
, aggiungere questa riga di codice.
WinRT.Interop.InitializeWithWindow.Initialize(fileSavePicker, App.WindowHandle);
MainPage ha dipendenze da DetailPage, motivo per cui è stata eseguita per prima la migrazione di DetailPage . Ma DetailPage ha dipendenze anche da MainPage, quindi non sarà ancora possibile eseguire la compilazione.
Migrazione della visualizzazione MainPage
La pagina principale dell'app rappresenta la visualizzazione che compare per prima quando si esegue l'app. Si tratta della pagina che carica le foto dalla cartella Samples incorporata nell'app di esempio e mostra una visualizzazione di anteprima affiancata.
Copiare i file del codice sorgente MainPage
Copiare MainPage.xaml
e MainPage.xaml.cs
dal progetto di origine a quello di destinazione nello stesso modo in cui sono stati copiati i file nei passaggi precedenti.
Migrazione del codice sorgente MainPage
- Eseguire le operazioni di ricerca/sostituzione seguenti (distinzione tra maiuscole/minuscole e parola intera) nel file
MainPage.xaml
appena incollato.
PhotoLab
=>PhotoLabWinUI
Sempre in
MainPage.xaml
, trovare il markupanimations:ReorderGridAnimation.Duration="400"
ed eliminarlo.Eseguire le operazioni di ricerca/sostituzione seguenti (distinzione tra maiuscole/minuscole e parola intera) nel file
MainPage.xaml.cs
appena incollato.
namespace PhotoLab
=>namespace PhotoLabWinUI
Windows.UI.Xaml
=>Microsoft.UI.Xaml
- Per il passaggio successivo, verrà apportata la modifica illustrata in ContentDialog e Popup. Quindi, sempre in
MainPage.xaml.cs
, nel metodo ShowSaveDialog, immediatamente prima della rigaContentDialogResult resultNotUsed = await unsupportedFilesDialog.ShowAsync();
, aggiungere questo codice.
if (Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
{
unsupportedFilesDialog.XamlRoot = this.Content.XamlRoot;
}
- Sempre in
MainPage.xaml.cs
, nel metodo OnNavigatedTo, eliminare le due righe di codice seguenti.
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
AppViewBackButtonVisibility.Collapsed;
Più avanti in questo case study verrà reintrodotta la funzionalità del pulsante Indietro appena rimossa.
- A questo punto, verificare che sia possibile compilare la soluzione di destinazione (ma non eseguirla ancora).
Spostamento a MainPage
L'app di esempio PhotoLab usa la logica di spostamento per passare inizialmente a MainPage (e quindi tra MainPage e DetailPage). Per altre informazioni sulle app Windows App SDK che necessitano di spostamento (e su quello che non ne hanno bisogno), vedere Devo implementare lo spostamento nella pagina?
Di conseguenza, le modifiche che verranno apportate successivamente supporteranno lo spostamento.
- In
MainWindow.xaml
eliminare l'elemento<StackPanel>
e sostituirlo con solo un elemento denominato<Frame>
. Il risultato è simile al seguente:
<Window ...>
<Frame x:Name="rootFrame"/>
</Window>
In
MainWindow.xaml.cs
eliminare il metodo myButton_Click.Sempre in
MainWindow.xaml.cs
, aggiungere la seguente riga di codice al costruttore.
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
rootFrame.Navigate(typeof(MainPage));
}
}
- A questo punto, verificare che sia possibile compilare la soluzione di destinazione (ma non eseguirla ancora).
Ripristino della funzionalità del pulsante Indietro
- In
DetailPage.xaml
l'elemento radice è un RelativePanel. Aggiungere il seguente markup all'interno di RelativePanel, immediatamente dopo l'elemento StackPanel.
<AppBarButton x:Name="BackButton" Click="BackButton_Click" Margin="0,0,12,0">
<SymbolIcon Symbol="Back"/>
</AppBarButton>
- In
DetailPage.xaml.cs
aggiungere le due righe di codice seguenti al metodo OnNavigatedTo, nella posizione indicata.
if (this.Frame.CanGoBack)
{
BackButton.Visibility = Microsoft.UI.Xaml.Visibility.Visible;
}
else
{
BackButton.Visibility = Microsoft.UI.Xaml.Visibility.Collapsed;
}
- Sempre in
DetailPage.xaml.cs
, aggiungere il gestore eventi seguente.
private void BackButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
Frame.GoBack();
}
Testare l'app migrata
A questo punto, compilare il progetto ed eseguire l'app per testarla. Selezionare un'immagine, impostare un livello di zoom, scegliere gli effetti e configurarli.