Skip to content

Commit 99bf6ff

Browse files
docs: Apply suggestions from review
Co-authored-by: Alvin Ashcraft <[email protected]>
1 parent 18c5ca7 commit 99bf6ff

File tree

1 file changed

+23
-23
lines changed

1 file changed

+23
-23
lines changed

hub/apps/get-started/uno-simple-photo-viewer.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ ms.localizationpriority: medium
1111

1212
# Tutorial: Build a simple photo viewer that targets multiple platforms
1313

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.
1515

1616
:::image type="content" source="images/uno/screenshot1.png" alt-text="Screenshot of UnoSimplePhoto app targeting web and WinUI desktop":::
1717

@@ -34,13 +34,13 @@ Launch Visual Studio, then click `Continue without code`. Click `Extensions` ->
3434

3535
:::image type="content" source="../images/uno/uno-manage-extensions.png" alt-text="Visual Studio Menu bar item that reads manage extensions":::
3636

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.
3838

3939
:::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":::
4040

4141
## Create an application
4242

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.
4444

4545
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.
4646

@@ -58,7 +58,7 @@ Create a new C# solution using the **Uno Platform App** type from Visual Studio'
5858

5959
Now you'll choose a base template to take your Simple Photo gallery application multi-platform.
6060

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.
6262

6363
:::image type="content" source="../images/uno/uno-vsix-new-project-options.png" alt-text="Uno solution template for project startup type":::
6464

@@ -87,7 +87,7 @@ Now that you've generated the functional starting point of your multi-platform W
8787

8888
### Copy the view
8989

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).
9191

9292
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:
9393

@@ -236,7 +236,7 @@ Uno Platform's multi-platform implementation of the controls found in the `Windo
236236
</Page>
237237
```
238238

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.
240240

241241
To bring this code-behind multi-platform, we should first move the following into the `MainPage.xaml.cs` file:
242242

@@ -455,13 +455,13 @@ public class ImageFileInfo : INotifyPropertyChanged
455455
}
456456
```
457457

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.
459459

460460
### Using preprocessor directives
461461

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.
463463

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:
465465

466466
```csharp
467467
private async Task GetItemsAsync()
@@ -489,9 +489,9 @@ private async Task GetItemsAsync()
489489
}
490490
```
491491

492-
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.
493493

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:
495495

496496
```csharp
497497
public async static Task<ImageFileInfo> LoadImageInfoAsync(StorageFile file)
@@ -507,13 +507,13 @@ public async static Task<ImageFileInfo> LoadImageInfoAsync(StorageFile file)
507507
}
508508
```
509509

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.
511511

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.
513513

514514
:::image type="content" source="images/uno/xaml-attached-layout-realizationrect.png" alt-text="Diagram of collection control viewport":::
515515

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:
517517

518518
```csharp
519519
private void ImageGridView_ContainerContentChanging(
@@ -543,7 +543,7 @@ ContainerContentChangingEventArgs args)
543543
}
544544
```
545545

546-
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:
547547

548548
```csharp
549549
private async void ShowImage(ListViewBase sender, ContainerContentChangingEventArgs args)
@@ -576,7 +576,7 @@ private async void ShowImage(ListViewBase sender, ContainerContentChangingEventA
576576
}
577577
```
578578

579-
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.
580580

581581
### Creating a separate code path for other platforms
582582

@@ -586,7 +586,7 @@ Update `ImageFileInfo.cs` to include a new property called `ImageSource` that wi
586586
public BitmapImage? ImageSource { get; private set; }
587587
```
588588

589-
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:
590590

591591
```csharp
592592
public ImageFileInfo(StorageFile imageFile,
@@ -599,7 +599,7 @@ public ImageFileInfo(StorageFile imageFile,
599599
}
600600
```
601601

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:
603603

604604
```csharp
605605
public ImageProperties? ImageProperties { get; }
@@ -623,7 +623,7 @@ public async Task<BitmapImage> GetImageSourceAsync()
623623
}
624624
```
625625

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:
627627

628628
- Modify the `ImageDimensions` property to use the null conditional operator:
629629

@@ -688,7 +688,7 @@ To prevent getting the value of `ImageProperties` when it's null, we will need t
688688
}
689689
```
690690

691-
With these edits, the `ImageFileInfo` class should contain the following code which has a newly-separated code path for platforms other than Windows:
691+
With these edits, the `ImageFileInfo` class should contain the following code. It now has a newly-separated code path for platforms other than Windows:
692692

693693
```csharp
694694
using Microsoft.UI.Xaml.Media.Imaging;
@@ -802,18 +802,18 @@ public class ImageFileInfo : INotifyPropertyChanged
802802
}
803803
```
804804

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.
806806

807807
### Using platform-specific XAML markup
808808

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:
810810

811811
```xml
812812
...
813813
xmlns:win="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
814814
```
815815

816-
Now, in `MainPage.xaml`, replace the `ItemsPanel` property setter on the GridView element with the following code:
816+
Now, in `MainPage.xaml`, replace the `ItemsPanel` property setter on the `GridView` element with the following code:
817817

818818
```xml
819819
win:ItemsPanel="{StaticResource ImageGridView_ItemsPanelTemplate}"

0 commit comments

Comments
 (0)