You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: hub/apps/get-started/uno-simple-photo-viewer.md
+23-23Lines changed: 23 additions & 23 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ ms.localizationpriority: medium
11
11
12
12
# Tutorial: Build a simple photo viewer that targets multiple platforms
13
13
14
-
After you've [created](/hub/apps/get-started/simple-photo-viewer-winui3.md) a starter simple photo viewer WinUI 3 app, you might be wondering how to reach more users without having to rewrite your app. This tutorial will use [Uno Platform](https://platform.uno/) to expand the reach of your existing C# WinUI 3 application enabling reuse of the business logic and UI layer across native mobile, web, and desktop. With only minimal changes to the simple photo viewer app, we'll be able to run a pixel-perfect copy of the app ported to these platforms.
14
+
After you've [created](/hub/apps/get-started/simple-photo-viewer-winui3.md) a starter simple photo viewer WinUI 3 app, you might be wondering how to reach more users without having to rewrite your app. This tutorial uses [Uno Platform](https://platform.uno/) to expand the reach of your existing C# WinUI 3 application enabling reuse of the business logic and UI layer across native mobile, web, and desktop. With only minimal changes to the simple photo viewer app, we can run a pixel-perfect copy of the app ported to these platforms.
15
15
16
16
:::image type="content" source="images/uno/screenshot1.png" alt-text="Screenshot of UnoSimplePhoto app targeting web and WinUI desktop":::
17
17
@@ -34,13 +34,13 @@ Launch Visual Studio, then click `Continue without code`. Click `Extensions` ->
34
34
35
35
:::image type="content" source="../images/uno/uno-manage-extensions.png" alt-text="Visual Studio Menu bar item that reads manage extensions":::
36
36
37
-
In the Extension Manager expand the **Online** node and search for `Uno`, install the `Uno Platform` extension, or download it from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=unoplatform.uno-platform-addin-2022), then restart Visual Studio.
37
+
In the Extension Manager expand the **Online** node and search for `Uno`, install the `Uno Platform` extension, or download and install it from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=unoplatform.uno-platform-addin-2022), then restart Visual Studio.
38
38
39
39
:::image type="content" source="../images/uno/uno-extensions.png" alt-text="Manage Extensions window in Visual Studio with Uno Platform extension as a search result":::
40
40
41
41
## Create an application
42
42
43
-
Now that we are ready to create a multi-platform application, the approach we'll take is to create a new Uno Platform application. We will copy code from the previous tutorial's **SimplePhotos** WinUI 3 project into our multi-platform project. This is possible because Uno Platform lets you reuse your existing codebase. For features dependent on OS APIs provided by each platform, you can easily make them work over time. This approach is especially useful if you have an existing application that you want to port to other platforms.
43
+
Now that we're ready to create a multi-platform application, the approach we'll take is to create a new Uno Platform application. We'll copy code from the previous tutorial's **SimplePhotos** WinUI 3 project into our multi-platform project. This is possible because Uno Platform lets you reuse your existing codebase. For features dependent on OS APIs provided by each platform, you can easily make them work over time. This approach is especially useful if you have an existing application that you want to port to other platforms.
44
44
45
45
Soon enough, you will be able to reap the benefits of this approach, as you can target more platforms with a familiar XAML flavor and the codebase you already have.
46
46
@@ -58,7 +58,7 @@ Create a new C# solution using the **Uno Platform App** type from Visual Studio'
58
58
59
59
Now you'll choose a base template to take your Simple Photo gallery application multi-platform.
60
60
61
-
The Uno Platform App template comes with two preset options that allow you to quickly get started with either a **Blank** solution or the **Default** configuration which includes references to the Uno.Material and Uno.Toolkit libraries. The Default configuration also includes Uno.Extensions which is used for dependency injection, configuration, navigation, and logging, and it uses MVUX in place of MVVM, making it a great starting point for rapidly building real-world applications.
61
+
The Uno Platform App template comes with two preset options that allow you to quickly get started with either a **Blank** solution or the **Default** configuration which includes references to the Uno.Material and Uno.Toolkit libraries. The Default configuration also includes Uno.Extensions which is used for dependency injection, configuration, navigation, and logging. In addition, it uses MVUX in place of MVVM, making it a great starting point for rapidly building real-world applications.
62
62
63
63
:::image type="content" source="../images/uno/uno-vsix-new-project-options.png" alt-text="Uno solution template for project startup type":::
64
64
@@ -87,7 +87,7 @@ Now that you've generated the functional starting point of your multi-platform W
87
87
88
88
### Copy the view
89
89
90
-
Because Uno Platform allows you to use the XAML flavor you're already familiar with, you can copy over the same code you created in the [previous tutorial](/hub/apps/get-started/simple-photo-viewer-winui3.md).
90
+
Because Uno Platform allows you to use the XAML flavor you're already familiar with, you can copy the same code over that you created in the [previous tutorial](/hub/apps/get-started/simple-photo-viewer-winui3.md).
91
91
92
92
Return to the **SimplePhotos** project from the previous tutorial. In the **Solution Explorer**, find the file named `MainWindow.xaml` and open it. Observe that the contents of the view are defined within a `Window` element rather than a `Page`. This is because the desktop project is a WinUI 3 application, which can use `Window` elements to define the contents of the view:
93
93
@@ -236,7 +236,7 @@ Uno Platform's multi-platform implementation of the controls found in the `Windo
236
236
</Page>
237
237
```
238
238
239
-
Recall that the desktop solution also had a `MainWindow.xaml.cs` file that contained code-behind which corresponds to the view. In the Uno Platform project, the code-behind for the `MainPage` view we've copied into is contained in the `MainPage.xaml.cs` file.
239
+
You may recall that the desktop solution also had a `MainWindow.xaml.cs` file that contained code-behind which corresponds to the view. In the Uno Platform project, the code-behind for the `MainPage` view we've copied into is contained in the `MainPage.xaml.cs` file.
240
240
241
241
To bring this code-behind multi-platform, we should first move the following into the `MainPage.xaml.cs` file:
242
242
@@ -455,13 +455,13 @@ public class ImageFileInfo : INotifyPropertyChanged
455
455
}
456
456
```
457
457
458
-
This class will serve as a model to represent the image files in the `GridView`. Although it should technically possible to run the app at this point, it may not render the images correctly or display their properties. In the next sections, we will make a set of changes to these copied files to make them compatible in a multi-platform context.
458
+
This class will serve as a model to represent the image files in the `GridView`. Although it should technically possible to run the app at this point, it may not render the images correctly or display their properties. In the next sections, we'll make a set of changes to these copied files to make them compatible in a multi-platform context.
459
459
460
460
### Using preprocessor directives
461
461
462
-
In the desktop project from the previous tutorial, the `MainPage.xaml.cs` file contains a `GetItemsAsync` method that enumerates items from a `StorageFolder` representing the installed package location. Because that location is not available on certain platforms such as WebAssembly, we will need to make changes to this method to make it compatible with all platforms. We will accordingly make some changes to the `ImageFileInfo` class to ensure compatibility.
462
+
In the desktop project from the previous tutorial, the `MainPage.xaml.cs` file contains a `GetItemsAsync` method that enumerates items from a `StorageFolder` representing the installed package location. Because that location is not available on certain platforms such as WebAssembly, we'll need to make changes to this method to make it compatible with all platforms. We'll accordingly make some changes to the `ImageFileInfo` class to ensure compatibility.
463
463
464
-
First, we will make changes to the `GetItemsAsync` method. Replace the `GetItemsAsync` method in the `MainPage.xaml.cs` file with the following code:
464
+
First, make the required changes to the `GetItemsAsync` method. Replace the `GetItemsAsync` method in the `MainPage.xaml.cs` file with the following code:
This method now uses a **preprocessor directive** to determine which code to execute based on the platform. On Windows, the method will get the `StorageFolder` representing the installed package location and get the `Samples` folder from it. On other platforms, the method will count up to 20 getting the image files from the `Samples` folder using a `Uri` to represent the image file.
492
+
This method now uses a **preprocessor directive** to determine which code to execute based on the platform. On Windows, the method gets the `StorageFolder` representing the installed package location and returns the `Samples` folder from it. On other platforms, the method counts up to 20, getting the image files from the `Samples` folder using a `Uri` to represent the image file.
493
493
494
-
Next, we will need to adjust the `LoadImageInfoAsync` method to accommodate the changes we made to the `GetItemsAsync` method. Replace the `LoadImageInfoAsync` method in the `MainPage.xaml.cs` file with the following code:
494
+
Next, adjust the `LoadImageInfoAsync` method to accommodate the changes we made to the `GetItemsAsync` method. Replace the `LoadImageInfoAsync` method in the `MainPage.xaml.cs` file with the following code:
@@ -507,13 +507,13 @@ public async static Task<ImageFileInfo> LoadImageInfoAsync(StorageFile file)
507
507
}
508
508
```
509
509
510
-
Similar to the `GetItemsAsync` method, this method now uses a preprocessor directive to determine which code to execute based on the platform. On Windows, the method will get the `ImageProperties` from the `StorageFile` and use it to create an `ImageFileInfo` object. On other platforms, the method will construct an `ImageFileInfo` object without the `ImageProperties` parameter. Later on, modifications will be made to the `ImageFileInfo` class to accommodate this change.
510
+
Similar to the `GetItemsAsync` method, this method now uses a preprocessor directive to determine which code to execute based on the platform. On Windows, the method gets the `ImageProperties` from the `StorageFile` and uses it to create an `ImageFileInfo` object. On other platforms, the method constructs an `ImageFileInfo` object without the `ImageProperties` parameter. Later, modifications will be made to the `ImageFileInfo` class to accommodate this change.
511
511
512
-
Controls like `GridView` allow for **progressive loading** of updated item container content as they are scrolled into the viewport. This is done by using the `ContainerContentChanging` event. In the desktop project from the previous tutorial, the `ImageGridView_ContainerContentChanging` method uses this event to load the image files into the `GridView`. Because certain aspects of this event are not supported on all platforms, we will need to make changes to this method to make it compatible with them.
512
+
Controls like `GridView` allow for **progressive loading** of updated item container content as they are scrolled into the viewport. This is done by using the `ContainerContentChanging` event. In the desktop project from the previous tutorial, the `ImageGridView_ContainerContentChanging` method uses this event to load the image files into the `GridView`. Because certain aspects of this event are not supported on all platforms, we'll need to make changes to this method to make it compatible with them.
513
513
514
514
:::image type="content" source="images/uno/xaml-attached-layout-realizationrect.png" alt-text="Diagram of collection control viewport":::
515
515
516
-
For instance, the `ContainerContentChangingEventArgs.Phase` property is currently unsupported on platforms other than Windows. We will need to make changes to the `ImageGridView_ContainerContentChanging` method to accommodate this change. Replace the `ImageGridView_ContainerContentChanging` method in the `MainPage.xaml.cs` file with the following code:
516
+
For instance, the `ContainerContentChangingEventArgs.Phase` property is currently unsupported on platforms other than Windows. We'll need to make changes to the `ImageGridView_ContainerContentChanging` method to accommodate this change. Replace the `ImageGridView_ContainerContentChanging` method in the `MainPage.xaml.cs` file with the following code:
The specialized callback is now only registered using `ContainerContentChangingEventArgs.RegisterUpdateCallback()` if the platform is Windows. Otherwise, the `ShowImage` method is called directly. We will also need to make changes to the `ShowImage` method to work alongside the changes made to the `ImageGridView_ContainerContentChanging` method. Replace the `ShowImage` method in the `MainPage.xaml.cs` file with the following code:
546
+
The specialized callback is now only registered using `ContainerContentChangingEventArgs.RegisterUpdateCallback()` if the platform is Windows. Otherwise, the `ShowImage` method is called directly. We'll also need to make changes to the `ShowImage` method to work alongside the changes made to the `ImageGridView_ContainerContentChanging` method. Replace the `ShowImage` method in the `MainPage.xaml.cs` file with the following code:
Again, preprocessor directives ensure that the `ContainerContentChangingEventArgs.Phase` property is only used where it is supported. We make use of the previously unused `GetImageSourceAsync()` method to load the image files into the `GridView` on platforms other than Windows. At this point, we will accommodate the changes made above by editing the `ImageFileInfo` class.
579
+
Again, preprocessor directives ensure that the `ContainerContentChangingEventArgs.Phase` property is only used on platforms where it is supported. We make use of the previously unused `GetImageSourceAsync()` method to load the image files into the `GridView` on platforms other than Windows. At this point, we'll accommodate the changes made above by editing the `ImageFileInfo` class.
580
580
581
581
### Creating a separate code path for other platforms
582
582
@@ -586,7 +586,7 @@ Update `ImageFileInfo.cs` to include a new property called `ImageSource` that wi
Because platforms like the web do not support advanced image file properties that are readily available on Windows, we should add a constructor overload that does not require an `ImageProperties` typed parameter. Add a new overload under the existing one using the following code:
589
+
Because platforms like the web do not support advanced image file properties that are readily available on Windows, we'll add a constructor overload that does not require an `ImageProperties` typed parameter. Add the new overload after the existing one using the following code:
590
590
591
591
```csharp
592
592
publicImageFileInfo(StorageFileimageFile,
@@ -599,7 +599,7 @@ public ImageFileInfo(StorageFile imageFile,
599
599
}
600
600
```
601
601
602
-
This constructor overload will be used to construct an `ImageFileInfo` object on platforms other than Windows. Since we did this, it makes sense to make the `ImageProperties` property nullable. Update the `ImageProperties` property to be nullable using the following code:
602
+
This constructor overload is used to construct an `ImageFileInfo` object on platforms other than Windows. Since we did this, it makes sense to make the `ImageProperties` property nullable. Update the `ImageProperties` property to be nullable using the following code:
603
603
604
604
```csharp
605
605
publicImageProperties?ImageProperties { get; }
@@ -623,7 +623,7 @@ public async Task<BitmapImage> GetImageSourceAsync()
623
623
}
624
624
```
625
625
626
-
To prevent getting the value of `ImageProperties` when it's null, we will need to make the following changes:
626
+
To prevent getting the value of `ImageProperties` when it's null, make the following changes:
627
627
628
628
- Modify the `ImageDimensions` property to use the null conditional operator:
629
629
@@ -688,7 +688,7 @@ To prevent getting the value of `ImageProperties` when it's null, we will need t
688
688
}
689
689
```
690
690
691
-
Withtheseedits, the `ImageFileInfo` classshouldcontainthefollowingcodewhichhasanewly-separatedcodepathfor platforms other than Windows:
691
+
Withtheseedits, the `ImageFileInfo` classshouldcontainthefollowingcode. Itnowhasanewly-separatedcodepathfor platforms other than Windows:
692
692
693
693
```csharp
694
694
using Microsoft.UI.Xaml.Media.Imaging;
@@ -802,18 +802,18 @@ public class ImageFileInfo : INotifyPropertyChanged
802
802
}
803
803
```
804
804
805
-
This `ImageFileInfo` class will be used to represent the image files in the `GridView`. Finally, we will make changes to the `MainPage.xaml` file to accommodate these changes.
805
+
This `ImageFileInfo` class is used to represent the image files in the `GridView`. Finally, we'll make changes to the `MainPage.xaml` file to accommodate the changes to the model.
806
806
807
807
### Using platform-specific XAML markup
808
808
809
-
There are a couple of items in our view markup which should be evaluated on Windows only. Add a new namespace on the `Page` element of the `MainPage.xaml` file like this:
809
+
There are a couple of items in our view markup which should only be evaluated on Windows. Add a new namespace on the `Page` element of the `MainPage.xaml` file like this:
0 commit comments