0
votes

I am learning UWP with prism but I can not get it to work. I created a project with the Prism Mvvm template and I have only added a model and a few controls. on running the app there is nothing in top textbox bound to MyPerson.Name the second textbox bound to Myperson.Age shows 25. When I click on the button the top text box show "Joe Blogs" and the second textbox remians the same. Nothing is being updated? Here is the XAML code:

<Page
x:Class="App5.Views.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prismMvvm="using:Prism.Windows.Mvvm"
prismMvvm:ViewModelLocator.AutoWireViewModel="True"
Style="{StaticResource PageStyle}"
mc:Ignorable="d">
<Grid x:Name="ContentArea" Margin="{StaticResource MediumLeftRightMargin}">
    <Grid.RowDefinitions>
        <RowDefinition Height="48" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <TextBlock
        x:Uid="Main_Title"
        Grid.Row="0"
        Style="{StaticResource PageTitleStyle}" />
    <Grid Grid.Row="1" Background="{ThemeResource SystemControlPageBackgroundChromeLowBrush}">
        <StackPanel>
            <TextBox
                Width="100"
                Height="100"
                Text="{x:Bind Path=ViewModel.MyPerson.Name, Mode=TwoWay}" />
            <TextBox
                Width="100"
                Height="100"
                Text="{x:Bind Path=ViewModel.MyPerson.Age, Mode=TwoWay}" />
            <Button
                Width="100"
                Height="100"
                HorizontalAlignment="Center"
                Click="Button_Click"
                Content="test" />
        </StackPanel>

    </Grid>
</Grid>

My model:

namespace App5.Models
{
  public class Person
  {
      public int Age { get; set; }
      public string Name { get; set; }
  }
}

My ViewModel:

using App5.Models;
using Prism.Windows.Mvvm;

namespace App5.ViewModels
{
    public class MainViewModel : ViewModelBase
    {
        private Person _myPerson;
        public Person MyPerson
        {
            get => _myPerson;
            set => SetProperty(ref _myPerson, value);
        }
        public MainViewModel()
        {
             MyPerson = new Person() { Age = 25, Name = "Bill Blogs" };

        }

    } 

}

My code behind:

using System;

using App5.ViewModels;

using Windows.UI.Xaml.Controls;

namespace App5.Views
{
    public sealed partial class MainPage : Page
    {
        private MainViewModel ViewModel => DataContext as MainViewModel;

        public MainPage()
        {
            InitializeComponent();

        }
        private void MainPage_Loaded(object sender, 
      Windows.UI.Xaml.RoutedEventArgs e)
    {
    }
    private void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
           ViewModel.MyPerson.Name = "Viv Blogs";
           ViewModel.MyPerson.Age = 50;
           ViewModel.MyPerson = ViewModel.MyPerson;
       }
   }

}

1
If you are directly binding to Data model objects ( in your case Person ), I would suggest that you also add the INotifyPropertychanged interface to them. This will enable data changes to automatically propagate to the UI. - Depechie
Ok but I thought prism did this for you. - Paul Stanley
No it does not, but you could use Fody to auto inject it... github.com/Fody/PropertyChanged - Depechie

1 Answers

2
votes

The Person class should implement INotifyPropertyChanged interface and raise change notifications:

public class Person : ViewModelBase
{
    private int _age;
    public int  Age
    {
        get => _age;
        set => SetProperty(ref _age, value);
    }

    private int _name;
    public int Name
    {
        get => _name;
        set => SetProperty(ref _name, value);
    }
}

You could then simply set the Age and Name properties of it:

private void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
    ViewModel.MyPerson.Name = "Viv Blogs";
    ViewModel.MyPerson.Age = 50;
}

For the MainViewModel to raise a change notification when you set the MyPerson property, you need to set the property to a new Person object:

private void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
    ViewModel.MyPerson = new MyPerson() { Name = "Viv Blogs", Age = 50 };
}