Reputation: 9298
I have a TabbedPage where I add entries and in the other tabs I list data. How can I refresh the data after I've added an entry to database using MVVM?
MainPage:
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:myMood.Views"
x:Class="myMood.Views.MainPage"
BackgroundImage="logo.png">
<local:Register></local:Register>
<local:Entries></local:Entries>
<local:Statistics></local:Statistics>
<local:Settings></local:Settings>
<local:About></local:About>
</TabbedPage>
Entries:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="myMood.Views.Entries"
Icon="ic_view_headline_white_24dp.png"
xmlns:viewModels="clr-namespace:myMood.ViewModels">
<ContentPage.BindingContext>
<viewModels:EntriesViewModel />
</ContentPage.BindingContext>
<ListView ItemsSource="{Binding MoodEntries}"
HasUnevenRows="True"
Margin="20">
<ListView.Header>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30*" />
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*" />
</Grid.ColumnDefinitions>
<Image Source="ic_date_range_black_24dp.png" Grid.Column="0" Grid.Row="0" HorizontalOptions="Center"></Image>
<Image Source="ic_local_hotel_black_24dp.png" Grid.Column="1" Grid.Row="0" HorizontalOptions="Center"></Image>
<Image Source="ic_directions_run_black_24dp.png" Grid.Column="2" Grid.Row="0" HorizontalOptions="Center"></Image>
<Image Source="ic_done_all_black_24dp.png" Grid.Column="3" Grid.Row="0" HorizontalOptions="Center"></Image>
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30*" />
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding EntryDate, StringFormat='{0:d/M}'}" Grid.Column="0" Grid.Row="0" HorizontalOptions="Center"></Label>
<Label Text="{Binding Sleep, StringFormat='{0:0.0}'}" Grid.Column="1" Grid.Row="0" HorizontalOptions="Center"></Label>
<Label Text="{Binding Stress, StringFormat='{0:0.0}'}" Grid.Column="2" Grid.Row="0" HorizontalOptions="Center"></Label>
<Label Text="{Binding AchivedGoals, StringFormat='{0:0.0}'}" Grid.Column="3" Grid.Row="0" HorizontalOptions="Center"></Label>
<Label Text="{Binding Comment, StringFormat='{0:0.0}'}" Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="1"></Label>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
ViewModel:
using myMood.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace myMood.ViewModels
{
public class EntriesViewModel
{
public List<MoodEntry> MoodEntries { get; set; }
public EntriesViewModel()
{
MoodEntries = App.MoodDatabase.GetMoodEntries();
}
}
}
Register Viewmodel:
namespace myMood.ViewModels
{
public class RegisterViewModel : INotifyPropertyChanged
{
public MoodEntry MoodEntry { get; set; }
public DateTime LowerLimitDate { get; set; }
public DateTime HighLimitDate { get; set; }
public Command SaveEntry
{
get
{
return new Command(() =>
App.MoodDatabase.SaveMoodEntry(MoodEntry));
}
}
public RegisterViewModel()
{
MoodEntry = App.MoodDatabase.GetMoodEntry(DateTime.Today);
if (MoodEntry == null)
MoodEntry = new MoodEntry();
LowerLimitDate = new DateTime(2018, 1, 1);
HighLimitDate = DateTime.Today;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Upvotes: 0
Views: 1371
Reputation: 154
You need to implement the INotifyPropertyChanged
Interface in your viewmodel. Because Currently the viewmodel sends no signal to the UI that the data has changed.
So your viewmodel should look like this:
public class EntriesViewModel : INotifyPropertyChanged
{
private List<MoodEntry> _moodEntries;
public List<MoodEntry> MoodEntries
{
get { return _moodEntries; }
set { _moodEntries = value; OnPropertyChanged(); }
}
public EntriesViewModel()
{
MoodEntries = App.MoodDatabase.GetMoodEntries();
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Upvotes: 2