mirror of
https://github.com/PacktPublishing/Learn-WinUI-3-Second-Edition.git
synced 2026-06-20 12:23:09 +00:00
Add completed solution for chapter 3
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace MyMediaCollection.ViewModels
|
||||
{
|
||||
public class BindableBase : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
protected bool SetProperty<T>(ref T originalValue, T newValue, [CallerMemberName] string propertyName = null)
|
||||
{
|
||||
if (Equals(originalValue, newValue))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
originalValue = newValue;
|
||||
OnPropertyChanged(propertyName);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using MyMediaCollection.Enums;
|
||||
using MyMediaCollection.Model;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MyMediaCollection.ViewModels
|
||||
{
|
||||
public partial class MainViewModel : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
private string selectedMedium;
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<MediaItem> items;
|
||||
[ObservableProperty]
|
||||
private IList<string> mediums;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(DeleteCommand))]
|
||||
private MediaItem selectedMediaItem;
|
||||
|
||||
private ObservableCollection<MediaItem> allItems;
|
||||
private int additionalItemCount = 1;
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
PopulateData();
|
||||
}
|
||||
|
||||
public void PopulateData()
|
||||
{
|
||||
var cd = new MediaItem
|
||||
{
|
||||
Id = 1,
|
||||
Name = "Classical Favorites",
|
||||
MediaType = ItemType.Music,
|
||||
MediumInfo = new Medium { Id = 1, MediaType = ItemType.Music, Name = "CD" }
|
||||
};
|
||||
|
||||
var book = new MediaItem
|
||||
{
|
||||
Id = 2,
|
||||
Name = "Classic Fairy Tales",
|
||||
MediaType = ItemType.Book,
|
||||
MediumInfo = new Medium { Id = 2, MediaType = ItemType.Book, Name = "Book" }
|
||||
};
|
||||
|
||||
var bluRay = new MediaItem
|
||||
{
|
||||
Id = 3,
|
||||
Name = "The Mummy",
|
||||
MediaType = ItemType.Video,
|
||||
MediumInfo = new Medium { Id = 3, MediaType = ItemType.Video, Name = "Blu Ray" }
|
||||
};
|
||||
|
||||
Items = new ObservableCollection<MediaItem>
|
||||
{
|
||||
cd,
|
||||
book,
|
||||
bluRay
|
||||
};
|
||||
|
||||
allItems = new ObservableCollection<MediaItem>(Items);
|
||||
|
||||
Mediums = new List<string>
|
||||
{
|
||||
"All",
|
||||
nameof(ItemType.Book),
|
||||
nameof(ItemType.Music),
|
||||
nameof(ItemType.Video)
|
||||
};
|
||||
|
||||
SelectedMedium = Mediums[0];
|
||||
}
|
||||
|
||||
partial void OnSelectedMediumChanged(string value)
|
||||
{
|
||||
Items.Clear();
|
||||
|
||||
foreach (var item in allItems)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value) ||
|
||||
value == "All" ||
|
||||
value == item.MediaType.ToString())
|
||||
{
|
||||
Items.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void AddEdit()
|
||||
{
|
||||
// Note this is temporary until
|
||||
// we use a real data source for items.
|
||||
const int startingItemCount = 3;
|
||||
|
||||
var newItem = new MediaItem
|
||||
{
|
||||
Id = startingItemCount + additionalItemCount,
|
||||
Location = LocationType.InCollection,
|
||||
MediaType = ItemType.Music,
|
||||
MediumInfo = new Medium { Id = 1, MediaType = ItemType.Music, Name = "CD" },
|
||||
Name = $"CD {additionalItemCount}"
|
||||
};
|
||||
|
||||
allItems.Add(newItem);
|
||||
Items.Add(newItem);
|
||||
additionalItemCount++;
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanDeleteItem))]
|
||||
public void Delete()
|
||||
{
|
||||
allItems.Remove(SelectedMediaItem);
|
||||
Items.Remove(SelectedMediaItem);
|
||||
}
|
||||
|
||||
private bool CanDeleteItem() => SelectedMediaItem != null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
using MyMediaCollection.Enums;
|
||||
using MyMediaCollection.Model;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MyMediaCollection.ViewModels
|
||||
{
|
||||
public class MainViewModel : BindableBase
|
||||
{
|
||||
private string selectedMedium;
|
||||
private ObservableCollection<MediaItem> items;
|
||||
private ObservableCollection<MediaItem> allItems;
|
||||
private IList<string> mediums;
|
||||
private MediaItem selectedMediaItem;
|
||||
private int additionalItemCount = 1;
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
PopulateData();
|
||||
}
|
||||
|
||||
public void PopulateData()
|
||||
{
|
||||
var cd = new MediaItem
|
||||
{
|
||||
Id = 1,
|
||||
Name = "Classical Favorites",
|
||||
MediaType = ItemType.Music,
|
||||
MediumInfo = new Medium { Id = 1, MediaType = ItemType.Music, Name = "CD" }
|
||||
};
|
||||
|
||||
var book = new MediaItem
|
||||
{
|
||||
Id = 2,
|
||||
Name = "Classic Fairy Tales",
|
||||
MediaType = ItemType.Book,
|
||||
MediumInfo = new Medium { Id = 2, MediaType = ItemType.Book, Name = "Book" }
|
||||
};
|
||||
|
||||
var bluRay = new MediaItem
|
||||
{
|
||||
Id = 3,
|
||||
Name = "The Mummy",
|
||||
MediaType = ItemType.Video,
|
||||
MediumInfo = new Medium { Id = 3, MediaType = ItemType.Video, Name = "Blu Ray" }
|
||||
};
|
||||
|
||||
items = new ObservableCollection<MediaItem>
|
||||
{
|
||||
cd,
|
||||
book,
|
||||
bluRay
|
||||
};
|
||||
|
||||
allItems = new ObservableCollection<MediaItem>(Items);
|
||||
|
||||
mediums = new List<string>
|
||||
{
|
||||
"All",
|
||||
nameof(ItemType.Book),
|
||||
nameof(ItemType.Music),
|
||||
nameof(ItemType.Video)
|
||||
};
|
||||
|
||||
selectedMedium = Mediums[0];
|
||||
}
|
||||
|
||||
public ObservableCollection<MediaItem> Items
|
||||
{
|
||||
get
|
||||
{
|
||||
return items;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref items, value);
|
||||
}
|
||||
}
|
||||
|
||||
public IList<string> Mediums
|
||||
{
|
||||
get
|
||||
{
|
||||
return mediums;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref mediums, value);
|
||||
}
|
||||
}
|
||||
|
||||
public string SelectedMedium
|
||||
{
|
||||
get
|
||||
{
|
||||
return selectedMedium;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref selectedMedium, value);
|
||||
|
||||
Items.Clear();
|
||||
|
||||
foreach (var item in allItems)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(selectedMedium) ||
|
||||
selectedMedium == "All" ||
|
||||
selectedMedium == item.MediaType.ToString())
|
||||
{
|
||||
Items.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MediaItem SelectedMediaItem
|
||||
{
|
||||
get => selectedMediaItem;
|
||||
set
|
||||
{
|
||||
SetProperty(ref selectedMediaItem, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddOrEditItem()
|
||||
{
|
||||
// Note this is temporary until
|
||||
// we use a real data source for items.
|
||||
const int startingItemCount = 3;
|
||||
|
||||
var newItem = new MediaItem
|
||||
{
|
||||
Id = startingItemCount + additionalItemCount,
|
||||
Location = LocationType.InCollection,
|
||||
MediaType = ItemType.Music,
|
||||
MediumInfo = new Medium { Id = 1, MediaType = ItemType.Music, Name = "CD" },
|
||||
Name = $"CD {additionalItemCount}"
|
||||
};
|
||||
|
||||
Items.Add(newItem);
|
||||
additionalItemCount++;
|
||||
}
|
||||
|
||||
public void DeleteItem()
|
||||
{
|
||||
Items.Remove(SelectedMediaItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
using MyMediaCollection.Enums;
|
||||
using MyMediaCollection.Model;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MyMediaCollection.ViewModels
|
||||
{
|
||||
public class MainViewModel : BindableBase
|
||||
{
|
||||
private string selectedMedium;
|
||||
private ObservableCollection<MediaItem> items;
|
||||
private ObservableCollection<MediaItem> allItems;
|
||||
private IList<string> mediums;
|
||||
private MediaItem selectedMediaItem;
|
||||
private int additionalItemCount = 1;
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
PopulateData();
|
||||
|
||||
DeleteCommand = new RelayCommand(DeleteItem, CanDeleteItem);
|
||||
|
||||
// No CanExecute param is needed for this command
|
||||
// because you can always add or edit items.
|
||||
AddEditCommand = new RelayCommand(AddOrEditItem);
|
||||
}
|
||||
|
||||
public void PopulateData()
|
||||
{
|
||||
var cd = new MediaItem
|
||||
{
|
||||
Id = 1,
|
||||
Name = "Classical Favorites",
|
||||
MediaType = ItemType.Music,
|
||||
MediumInfo = new Medium { Id = 1, MediaType = ItemType.Music, Name = "CD" }
|
||||
};
|
||||
|
||||
var book = new MediaItem
|
||||
{
|
||||
Id = 2,
|
||||
Name = "Classic Fairy Tales",
|
||||
MediaType = ItemType.Book,
|
||||
MediumInfo = new Medium { Id = 2, MediaType = ItemType.Book, Name = "Book" }
|
||||
};
|
||||
|
||||
var bluRay = new MediaItem
|
||||
{
|
||||
Id = 3,
|
||||
Name = "The Mummy",
|
||||
MediaType = ItemType.Video,
|
||||
MediumInfo = new Medium { Id = 3, MediaType = ItemType.Video, Name = "Blu Ray" }
|
||||
};
|
||||
|
||||
items = new ObservableCollection<MediaItem>
|
||||
{
|
||||
cd,
|
||||
book,
|
||||
bluRay
|
||||
};
|
||||
|
||||
allItems = new ObservableCollection<MediaItem>(Items);
|
||||
|
||||
mediums = new List<string>
|
||||
{
|
||||
"All",
|
||||
nameof(ItemType.Book),
|
||||
nameof(ItemType.Music),
|
||||
nameof(ItemType.Video)
|
||||
};
|
||||
|
||||
selectedMedium = Mediums[0];
|
||||
}
|
||||
|
||||
public ObservableCollection<MediaItem> Items
|
||||
{
|
||||
get
|
||||
{
|
||||
return items;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref items, value);
|
||||
}
|
||||
}
|
||||
|
||||
public IList<string> Mediums
|
||||
{
|
||||
get
|
||||
{
|
||||
return mediums;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref mediums, value);
|
||||
}
|
||||
}
|
||||
|
||||
public string SelectedMedium
|
||||
{
|
||||
get
|
||||
{
|
||||
return selectedMedium;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref selectedMedium, value);
|
||||
|
||||
Items.Clear();
|
||||
|
||||
foreach (var item in allItems)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(selectedMedium) ||
|
||||
selectedMedium == "All" ||
|
||||
selectedMedium == item.MediaType.ToString())
|
||||
{
|
||||
Items.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MediaItem SelectedMediaItem
|
||||
{
|
||||
get => selectedMediaItem;
|
||||
set
|
||||
{
|
||||
SetProperty(ref selectedMediaItem, value);
|
||||
((RelayCommand)DeleteCommand).RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand AddEditCommand { get; set; }
|
||||
|
||||
public void AddOrEditItem()
|
||||
{
|
||||
// Note this is temporary until
|
||||
// we use a real data source for items.
|
||||
const int startingItemCount = 3;
|
||||
|
||||
var newItem = new MediaItem
|
||||
{
|
||||
Id = startingItemCount + additionalItemCount,
|
||||
Location = LocationType.InCollection,
|
||||
MediaType = ItemType.Music,
|
||||
MediumInfo = new Medium { Id = 1, MediaType = ItemType.Music, Name = "CD" },
|
||||
Name = $"CD {additionalItemCount}"
|
||||
};
|
||||
|
||||
allItems.Add(newItem);
|
||||
Items.Add(newItem);
|
||||
additionalItemCount++;
|
||||
}
|
||||
|
||||
public ICommand DeleteCommand { get; set; }
|
||||
|
||||
public void DeleteItem()
|
||||
{
|
||||
allItems.Remove(SelectedMediaItem);
|
||||
Items.Remove(SelectedMediaItem);
|
||||
}
|
||||
|
||||
private bool CanDeleteItem() => selectedMediaItem != null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MyMediaCollection.ViewModels
|
||||
{
|
||||
public class RelayCommand : ICommand
|
||||
{
|
||||
private readonly Action action;
|
||||
private readonly Func<bool> canExecute;
|
||||
|
||||
public RelayCommand(Action action)
|
||||
: this(action, null)
|
||||
{
|
||||
}
|
||||
|
||||
public RelayCommand(Action action, Func<bool> canExecute)
|
||||
{
|
||||
if (action == null)
|
||||
throw new ArgumentNullException(nameof(action));
|
||||
|
||||
this.action = action;
|
||||
this.canExecute = canExecute;
|
||||
}
|
||||
|
||||
public bool CanExecute(object parameter) => canExecute == null || canExecute();
|
||||
|
||||
public void Execute(object parameter) => action();
|
||||
|
||||
public event EventHandler CanExecuteChanged;
|
||||
|
||||
public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user