// Window1.xaml.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel; // INotifyPropertyChanged

namespace WithoutBinding {

  public class Person : INotifyPropertyChanged {
    // INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    protected void Notify(string propName) {
      if( this.PropertyChanged != null ) {
        PropertyChanged(this, new PropertyChangedEventArgs(propName));
      }
    }

    string name;
    public string Name {
      get { return this.name; }
      set {
        if( this.name == value ) { return; }
        this.name = value;
        Notify("Name");
      }
    }

    int age;
    public int Age {
      get { return this.age; }
      set {
        if( this.age == value ) { return; }
        this.age = value;
        Notify("Age");
      }
    }

    public Person() { }
    public Person(string name, int age) {
      this.name = name;
      this.age = age;
    }
  }

  public partial class Window1 : Window {
    Person person = new Person("Tom", 11);

    public Window1() {
      InitializeComponent();

      // Fill initial person fields
      this.nameTextBox.Text = person.Name;
      this.ageTextBox.Text = person.Age.ToString();

      // Watch for changes in Tom's properties
      person.PropertyChanged += person_PropertyChanged;

      // Watch for changes in the controls
      this.nameTextBox.TextChanged += nameTextBox_TextChanged;
      this.ageTextBox.TextChanged += ageTextBox_TextChanged;

      // Handle the birthday button click event
      this.birthdayButton.Click += birthdayButton_Click;
    }

    void person_PropertyChanged(object sender, PropertyChangedEventArgs e) {

      switch( e.PropertyName ) {
        case "Name":
        this.nameTextBox.Text = person.Name;
        break;

        case "Age":
        this.ageTextBox.Text = person.Age.ToString();
        break;
      }
    }

    void nameTextBox_TextChanged(object sender, TextChangedEventArgs e) {
      person.Name = nameTextBox.Text;
    }

    void ageTextBox_TextChanged(object sender, TextChangedEventArgs e) {
      int age = 0;
      if( int.TryParse(ageTextBox.Text, out age) ) {
        person.Age = age;
      }
    }

    void birthdayButton_Click(object sender, RoutedEventArgs e) {
      ++person.Age;

      // nameTextBox_TextChanged and ageTextBox_TextChanged
      // will make sure the Person object is up to date
      // when it's displayed in the message box
      MessageBox.Show(
        string.Format(
          "Happy Birthday, {0}, age {1}!",
          person.Name,
          person.Age),
        "Birthday");
    }

  }
}
