Skip to content

Commit 85f7501

Browse files
committed
Finalize ReadMe.adoc
1 parent 465b506 commit 85f7501

File tree

1 file changed

+27
-31
lines changed
  • src/Avalonia.Samples/CompleteApps/Avalonia.MusicStore

1 file changed

+27
-31
lines changed

src/Avalonia.Samples/CompleteApps/Avalonia.MusicStore/README.adoc

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ A new project will be created with the following solution folders and files:
7474
.The basic structure of the created project
7575
image::_docs/2_rider_proj_structure.png[This is the structure of the creates project]
7676

77-
NOTE: The file names may differ a little. For example "MainWindowViewModel.cs" may be named "MainViewModel.cs" depending on the IDE you are using.
77+
NOTE: The file names may differ a little. For example "MainViewModel.cs" may be named "MainViewModel.cs" depending on the IDE you are using.
7878

7979
==== Update Project Dependencies if needed
8080

@@ -471,7 +471,7 @@ Below is a stripped down diagram showing the message flow between the components
471471

472472
```mermaid
473473
graph TD;
474-
A[MainWindowViewModel] -->|Send PurchaseAlbumMessage| B(MainWindow)
474+
A[MainViewModel] -->|Send PurchaseAlbumMessage| B(MainWindow)
475475
B -->|Show MusicStoreWindow<br>await AlbumViewModel| C[MusicStoreWindow]
476476
C -->|BuyMusic| D[MusicStoreViewModel]
477477
D -->|Send MusicStoreClosedMessage<br>with SelectedAlbum| C
@@ -574,8 +574,8 @@ public MainWindow()
574574
```
575575

576576
==== Send the Message from the ViewModel
577-
Now, update the `AddAlbumAsync()` method inside `MainWindowViewModel` to send `PurchaseAlbumMessage` when the user clicks on the store button.
578-
- Open **MainWindowViewModel.cs**
577+
Now, update the `AddAlbumAsync()` method inside `MainViewModel` to send `PurchaseAlbumMessage` when the user clicks on the store button.
578+
- Open **MainViewModel.cs**
579579
- Locate the `AddAlbumAsync()` method that we added in the previous steps.
580580
- Edit `AddAlbumAsync()` as shown:
581581
```csharp
@@ -1514,10 +1514,10 @@ private bool CanBuyMusic() => SelectedAlbum != null;
15141514
[NotifyCanExecuteChangedFor(nameof(BuyMusicCommand))]
15151515
public partial AlbumViewModel? SelectedAlbum { get; set; }
15161516
```
1517-
==== Implement the Album Existence Check in MainWindowViewModel
1518-
The MainWindowViewModel will handle the `CheckAlbumAlreadyExistsMessage` to determine if the selected album is already in the user's collection. To do this, you will implement a message handler that checks the observable collection of albums for the presence of the selected album.
1517+
==== Implement the Album Existence Check in MainViewModel
1518+
The MainViewModel will handle the `CheckAlbumAlreadyExistsMessage` to determine if the selected album is already in the user's collection. To do this, you will implement a message handler that checks the observable collection of albums for the presence of the selected album.
15191519

1520-
In the **MainWindowViewModel.cs** file, add the following code to the constructor:
1520+
In the **MainViewModel.cs** file, add the following code to the constructor:
15211521
```csharp
15221522
public MainViewModel()
15231523
{
@@ -1572,8 +1572,6 @@ Your next step is bind the **Buy Album** button to the relay command in the musi
15721572

15731573
You will see the dialog close, but nothing happens in the main window!
15741574

1575-
// Todo: Continue here...
1576-
15771575
=== Add Items to the User's Collection
15781576

15791577
On this page you will implement a collection of albums that the user has selected using the search dialog and the **Buy Album** button, and display them in the main window.
@@ -1585,9 +1583,9 @@ Your first step here is to add an observable collection to the main window view
15851583
Follow this procedure:
15861584

15871585
- Stop the app if it is running.
1588-
- Locate and open the **MainWindowViewModel.cs** file.
1586+
- Locate and open the **MainViewModel.cs** file.
15891587
- Add an observable collection, as shown:
1590-
1588+
+
15911589
```csharp
15921590
public ObservableCollection<AlbumViewModel> Albums { get; } = new();
15931591
```
@@ -1596,7 +1594,7 @@ public ObservableCollection<AlbumViewModel> Albums { get; } = new();
15961594

15971595
Your next step is to alter the `AddAlbumAsync` command so that it adds the dialog return object (an `AlbumViewModel`) to the observable collection. Follow this procedure:
15981596

1599-
- In the same **MainWindowViewModel.cs** file update the `AddAlbumAsync()` command method:
1597+
- In the same **MainViewModel.cs** file update the `AddAlbumAsync()` command method:
16001598

16011599
```csharp
16021600
[RelayCommand]
@@ -1618,13 +1616,13 @@ To add the items control and its data template, follow this procedure:
16181616

16191617
- Locate and open the **MainWindow.axaml** file.
16201618
- Add the following namespace declaration to the `<Window>` element:
1621-
1619+
+
16221620
```xml
16231621
xmlns:views="clr-namespace:Avalonia.MusicStore.Views"
16241622
```
16251623

16261624
- Under the button element, add the XAML as shown:
1627-
1625+
+
16281626
```xml
16291627
<ScrollViewer VerticalScrollBarVisibility="Auto" Margin="0 40 0 0">
16301628
<ItemsControl ItemsSource="{Binding Albums}">
@@ -1650,6 +1648,7 @@ xmlns:views="clr-namespace:Avalonia.MusicStore.Views"
16501648
- Click **Buy Album**.
16511649
- Repeat another time.
16521650

1651+
.Showing the user's album collection in the main window
16531652
image::_docs/21_user_album_collection.png[User's bought albums]
16541653

16551654
You will see the user's album collection building as you search and select. However, if you stop the app running and then start it again, the collection reverts to empty.
@@ -1668,7 +1667,7 @@ Follow this procedure to add persistence services (save and load) to the album m
16681667
- Stop the app if it is running.
16691668
- Locate and open the **Album.cs** file in the **/Models** folder.
16701669
- Add the code to implement save to disk, as shown:
1671-
1670+
+
16721671
```csharp
16731672
public async Task SaveAsync()
16741673
{
@@ -1695,7 +1694,7 @@ private static async Task SaveToStreamAsync(Album data, Stream stream)
16951694
```
16961695

16971696
- Add the code to implement load from disk, as shown:
1698-
1697+
+
16991698
```csharp
17001699
public static async Task<Album> LoadFromStream(Stream stream)
17011700
{
@@ -1713,7 +1712,8 @@ public static async Task<IEnumerable<Album>> LoadCachedAsync()
17131712

17141713
foreach (var file in Directory.EnumerateFiles("./Cache"))
17151714
{
1716-
if (!string.IsNullOrWhiteSpace(new DirectoryInfo(file).Extension)) continue;
1715+
if (!string.IsNullOrWhiteSpace(new DirectoryInfo(file).Extension))
1716+
continue;
17171717

17181718
await using var fs = File.OpenRead(file);
17191719
results.Add(await Album.LoadFromStream(fs).ConfigureAwait(false));
@@ -1727,9 +1727,9 @@ public static async Task<IEnumerable<Album>> LoadCachedAsync()
17271727

17281728
Your next step is to add a method to the album view model that it can call the business service persistence save methods:
17291729

1730-
`SaveAsync` - persists the album text data as a JSON file,
1730+
SaveAsync:: persists the album text data as a JSON file,
17311731

1732-
`SaveCoverBitmapStream` - saves the cover art as a bitmap (.BMP) file.
1732+
SaveCoverBitmapStream:: saves the cover art as a bitmap (.BMP) file.
17331733

17341734
To alter the album view model , follow this procedure:
17351735

@@ -1741,15 +1741,15 @@ public async Task SaveToDiskAsync()
17411741
{
17421742
await _album.SaveAsync();
17431743

1744-
if (Cover != null)
1744+
if (await LoadCoverAsync() is Bitmap cover)
17451745
{
17461746
var bitmap = Cover;
17471747

17481748
await Task.Run(() =>
17491749
{
17501750
using (var fs = _album.SaveCoverBitmapStream())
17511751
{
1752-
bitmap.Save(fs);
1752+
cover.Save(fs);
17531753
}
17541754
});
17551755
}
@@ -1764,7 +1764,7 @@ Lastly, you will call the new album view model persistence method `SaveToDiskAsy
17641764

17651765
To alter the main window view model, follow this procedure:
17661766

1767-
- Locate and open the **MainWindowViewModel.cs** file.
1767+
- Locate and open the **MainViewModel.cs** file.
17681768
- Add the code `await result.SaveToDiskAsync();` as shown below.
17691769

17701770
Your code to initialize the relay command will now look like this:
@@ -1823,7 +1823,7 @@ You have already added code to the business service that can load both the files
18231823
Follow this procedure to add a method to load the user's album collection from disk:
18241824

18251825
- Stop the app if it is running
1826-
- Locate and open the **MainWindowViewModel.cs** file.
1826+
- Locate and open the **MainViewModel.cs** file.
18271827
- Add the code as shown:
18281828

18291829
```csharp
@@ -1834,23 +1834,18 @@ private async void LoadAlbums()
18341834
{
18351835
Albums.Add(album);
18361836
}
1837-
var coverTasks = albums.Select(album => album.LoadCover());
1838-
await Task.WhenAll(coverTasks);
18391837
}
1840-
18411838
```
18421839

18431840
As you can see this method uses the business service to load the list of albums from the disk cache. It then transforms each data model (`Album` class) into a view model (`AlbumViewModel` class). After this all the album view models are added to the observable collection - this will instantly update the UI with the text data for the albums.
18441841

1845-
You will notice that after the JSON album files are loaded, the second loop loads the cover art image files. This provides your user with visual feedback as quickly as possible (in the form of album tiles with text and the placeholder music note icon) about what albums are in the collection. The cover art is then loaded asynchronously. This ensures that the app remains responsive during the image loading process.
1846-
18471842
Your next step is to schedule the `LoadAlbum` method to run when the app starts:
18481843

1849-
- Keep the **MainWindowViewModel.cs** file open.
1850-
- Call LoadAlbums() from the MainWindowViewModel constructor:
1844+
- Keep the **MainViewModel.cs** file open.
1845+
- Call LoadAlbums() from the MainViewModel constructor:
18511846

18521847
```csharp
1853-
public MainWindowViewModel()
1848+
public MainViewModel()
18541849
{
18551850
LoadAlbums();
18561851
}
@@ -1859,6 +1854,7 @@ With this change, now the app will automatically load previously added albums ev
18591854

18601855
- Click **Debug** to compile and run the project.
18611856

1857+
.Well done, this is the final result of the Music Store App tutorial
18621858
image::_docs/22_final_result.png[Final result]
18631859

18641860
=== Conclusion

0 commit comments

Comments
 (0)