WPF - Why are changes to an object for a simple data-binding not reflected back to the target in the main window?
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;}
}
}
}
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
.
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.
精彩评论