I've searched and read loads of similar threads, as well as watched some videos, but I'm running into issues and I think it boils down to some misunderstanding. I'm using MVVM with UWP development to study for the 70-357 exam.
My goal: Push a button in my XAML page, have it change a property of an object in my ViewModel, then have that value reflected in the databinding in my XAML view.
In my project I have the following:
MainPage XAML
<StackPanel Name="HPStack" Margin="0,0,10,0">
<Button Name="HPIncrease" Click="{x:Bind CharacterViewModel.HPIncrease_Click}" Content="+" HorizontalAlignment="Center"/>
<TextBlock Name="HPTB" Text="{x:Bind CharacterViewModel.myCharacter.CurrentHP}" Margin="0,0,5,0" HorizontalAlignment="Center"/>
<Button Name="HPDecrease" Click="{x:Bind CharacterViewModel.HPDecrease_Click}" Content="-" HorizontalAlignment="Center"/>
</StackPanel>
MainPage C#
public CharacterDetailsViewModel CharacterViewModel;
public MainPage()
{
this.InitializeComponent();
CharacterViewModel = new CharacterDetailsViewModel();
}
Character View Model (much of this code coming from the explanation I saw here
public class CharacterDetailsViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
//App data
private Character _myCharacter;
public Character myCharacter
{
set
{
_myCharacter = value;
OnPropertyChanged();
}
get { return _myCharacter; }
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
//Constructors
public CharacterDetailsViewModel()
{
_myCharacter = new Character(12, 12, 12, 12, 12, 12);
}
//buttons
public void HPIncrease_Click(object sender, RoutedEventArgs e)
{
//TODO probably fix this
myCharacter.CurrentHP++;
}
public void HPDecrease_Click(object sender, RoutedEventArgs e)
{
myCharacter.CurrentHP--;
}
}
Character Model (cutting out a lot of the irrelevant properties)
public class Character
{
public int TotalHP { get; set; } //TODO not public
public int CurrentHP {get;set;} //TODO check vs total HP and 0
//constructor for creating a new character with provided stats
public Character (int strength, int dexterity, int constitution, int intelligence, int wisdom, int charisma)
{
this.TotalHP = 50;
this.CurrentHP = 45;
}
}
- All of my properties seem to find correctly initially
- When I click the buttons to change the CurrentHP I don't see this reflected on the XAML
- I know about prism and template 10 existing. I do not want to use them as I am writing this code to understand these things better in preparation for a certification. In the future I will likely leverage them, but I am trying to figure out what I'm doing wrong in this context.
My understanding so far has been that I should only be putting INotfyPropertyChanged on the ViewModel and it can handle alerting that any property inside of a custom object (Character in this case) has changed.
Am I wrong in this? Do I need INotifyPropertyChanged on my Character class to correctly alert XAML to these changes?
Thanks for any input here.