tags:

views:

57

answers:

2

I am currently learning WPF (C#) and have taken the following simple data binding example from a text book which I am trying to get working.

The example displays a simple window containing a name and age textbox and a Birthday button.

The name and age that are display are represented in a Person object. When the birthday button is clicked the age is incremented and a message box is displayed.

The message box displays "Happy Birthday, [Name], age [++Age]".

E.g. If the name on screen is Dangerous and the age is 28 then when you click the Birthday button the message box will state "Happy Birthday, Dangerous, age 29".

The age is incremented correctly in the Person object but this information is not reflected back to the screen via the binding. However, if you alter the name or age field on the screen then this information is correctly updated in the Person object.

The example in the book states that I should see the updated age reflected back on the screen. I’m probably missing something simple but I have spent some time trying to correct this but don’t know what is wrong? Thanks in advance for any help with this example.

The XAML to display the window:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel Name="stack">
        <TextBlock>Name:</TextBlock>
        <TextBox Text="{Binding Path=Name}"/>
        <TextBlock>Age:</TextBlock>
        <TextBox Text="{Binding Path=Age}"/>
        <Button Name="birthdayButton">Birthday</Button>
    </StackPanel>
</Window>

The code behind:

using System; using System.Windows; using System.Windows.Controls;

namespace WpfApplication1 {
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        Person person = new Person("Dangerous", 28);

        public Window1()
        {
            InitializeComponent();

            stack.DataContext = person;

            this.birthdayButton.Click += birthdayButton_Click;
        }

        void birthdayButton_Click(object sender, RoutedEventArgs e)
        {
            ++person.Age;
            MessageBox.Show(
                string.Format("Happy Birthday, {0}, age {1}!",
                    person.Name,
                    person.Age),
                "Birthday");
        }
    }

    public class Person
    {
        string name;
        int age;

        public Person() { }

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

        public string Name
        {
            get {return this.name;}
            set {this.name = value;}
        }

        public int Age
        {
            get {return this.age;}
            set {this.age = value;}
        }
    }
}
A: 

Try setting in the binding:

<TextBox Text="{Binding UpdateSourceTrigger=PropertyChanged}"/>

Or set it to Explicit and update it manually via the Button Click event handler, becuase the default for TextBox is LostFocus, and clicking a button doesn't lose the focus from the TextBox.

For more info read: Binding.UpdateSourceTrigger property.

Shimmy
A: 

First of all you need <TextBox Text="{Binding Path=Age, Mode=TwoWay}"/> Your Person object may also have to implement INotifyPropertyChanged and raise the proper event when the age changes. Check here for an example of how to implement INotifyPropertyChanged.

klausbyskov
@klausbyskov: If he didn't implement the INotifyPropertyChanged then for sure that's the reason.Regarding the Mode=TwoWay - it's unnescessary; when a Binding is initiated to TextBox.Text property, it's default Mode is TwoWay.
Shimmy
I was missing the INotifyPropertyChanged and after changing my Person class to implement this interface and raising the event after Age changes I can confirm that all is now working.Additionally, Shimmy was right to say that Mode=TwoWay is not required.Thanks for the help.
Dangerous