public class Movie { public string Title { get; set; } public string Rating { get; set; } }
public class Theater { public string Name { get; set; } public List<Movie> Movies { get; set; } public Theater() { Name = "Rialto"; // Load some initial movies Movies = new List<Movie> { new Movie { Title = "Wonder Woman", Rating = "PG-13" }, new Movie { Title = "Spider-Man", Rating = "PG-13" }, new Movie { Title = "Justice League", Rating = "PG-13" } }; } }
INotifyPropertyChanged
so the View is notified when the Model
changes
public class MovieViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private Movie movie; public MovieViewModel() { this.movie = new Movie(); } public string Title { get { return movie.Title; } set { movie.Title = value; NotifyPropertyChanged(); } } public string Rating { get { return movie.Rating; } set { movie.Rating = value; NotifyPropertyChanged(); } } private void NotifyPropertyChanged([CallerMemberName] String property = "") { // Notify any controls bound to the ViewModel that the property changed PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } }
ObservableCollection
that provides notifications to ListView when items are added or removed
public class TheaterViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private Theater theater; public ObservableCollection<MovieViewModel> Movies { get; set; } public string Name { get { return theater.Name; } set { theater.Name = value; OnPropertyChanged(this, new PropertyChangedEventArgs("Name")); } } public TheaterViewModel() { this.theater = new Theater(); Movies = new ObservableCollection<MovieViewModel>(); // Create ViewModels for each Movie foreach (var movie in theater.Movies) { var newMovie = new MovieViewModel { Title = movie.Title, Rating = movie.Rating }; newMovie.PropertyChanged += OnPropertyChanged; Movies.Add(newMovie); } } private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { // Theater name or MovieViewModel changed, so let UI know PropertyChanged?.Invoke(sender, e); } }
<Page x:Class="UwpMovieMvvm.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:UwpMovieMvvm.ViewModels" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <TextBox x:Name="titleTextBox" Text="{x:Bind Movie.Title, Mode=TwoWay}" /> <TextBox x:Name="ratingTextBox" Text="{x:Bind Movie.Rating, Mode=TwoWay}" /> <Button x:Name="addButton" Content="Add Movie" Click="addButton_Click" /> <ListView x:Name="movieListView" Height="155" Width="200" HorizontalAlignment="Left" ItemsSource="{x:Bind Theater.Movies, Mode=OneWay}"> <ListView.ItemTemplate> <DataTemplate x:DataType="local:MovieViewModel"> <StackPanel> <TextBlock Text="{x:Bind Title, Mode=OneWay}" FontWeight="Bold"/> <TextBlock Text="{x:Bind Rating, Mode=OneWay}"/> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> <Button x:Name="deleteButton" Content="Delete Movie" Click="deleteButton_Click" /> </StackPanel> </Page>
public sealed partial class MainPage : Page { // XAML binds to these properties public TheaterViewModel Theater { get; set; } public MovieViewModel Movie { get; set; } public MainPage() { this.InitializeComponent(); // Create ViewModels Movie = new MovieViewModel(); Theater = new TheaterViewModel(); } private void addButton_Click(object sender, RoutedEventArgs e) { // Add new movie to list Theater.Movies.Add(new MovieViewModel { Title = Movie.Title, Rating = Movie.Rating }); } private void deleteButton_Click(object sender, RoutedEventArgs e) { // Delete selected movie from ObservableCollection to update UI if (movieListView.SelectedIndex > -1) { Theater.Movies.RemoveAt(movieListView.SelectedIndex); } } }
private void addButton_Click(object sender, RoutedEventArgs e) { // TODO: Create AddMovie() to add to Movies and to Theater model's movie list Theater.AddMovie(new MovieViewModel { Title = Movie.Title, Rating = Movie.Rating }); } private void deleteButton_Click(object sender, RoutedEventArgs e) { // TODO: Create DeleteMovie() to remove from Movies and remove from Theater model's movie list if (movieListView.SelectedIndex > -1) { Theater.DeleteMovie(movieListView.SelectedIndex); } }