Reputation: 6409
I've been playing about with data binding and using the INotifiedProperty interface (including the new .Net 4.5 CallerMemberName attribute).
All is working well but I can't understand why updating an object's property refreshes the label it's bound to but refreshing the object itself doesn't re-fresh the label.
For example, if I have the following Window:
<Grid Name="TestGrid">
<!-- Grid definitions here -->
<Label Grid.Column="0" Grid.Row="0">The value is :</Label>
<Label Grid.Column="1" Grid.Row="0" Content="{Binding TestVal1}"/>
<Button Grid.Column="0" Grid.Row="1" Click="Button_Click_1">Refresh</Button>
<Button Grid.Column="1" Grid.Row="1" Click="Button_Click_2">New class instance</Button>
</Grid>
With the following code behind it:
public MainWindow()
{
InitializeComponent();
TestGrid.DataContext = TestClass1;
}
public TestClass TestClass1 = new TestClass();
private void Button_Click_1(object sender, RoutedEventArgs e)
{
TestClass1.ChangeTestVal1();
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
TestClass1 = new TestClass();
}
Which is bound the following class:
public class TestClass : INotifyPropertyChanged
{
public TestClass()
{
ChangeTestVal1();
}
public event PropertyChangedEventHandler PropertyChanged;
internal void OnPropertyChanged([CallerMemberName] String caller = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(caller));
}
}
private string _TestVal1;
public string TestVal1
{
get { return _TestVal1; }
set
{
if (value != _TestVal1)
{
_TestVal1 = value;
OnPropertyChanged();
}
}
}
public void ChangeTestVal1()
{
TestVal1 = "TestVal1 = " + DateTime.Now.ToString("dd-MMM-yyyy HH:mm:ss");
}
The result of is that clicking the "Refresh" button works and clicking the "New class instance" doesn't.
My question is, I know I can add "TestGrid.DataContext = TestClass1" to the code for the second button to get it to work but surely it should detect the instance of the TestClass changing when it's refreshed? Am I setting the binding up incorrectly?
Upvotes: 1
Views: 97
Reputation: 52133
The actual update for the binding is triggered via:
OnPropertyChanged();
which is in turn triggered when you set the property, not when you set the whole class. So setting the class has not visible effect in the label, as expected.
Upvotes: 0
Reputation: 1194
That's happening because the data context has the reference to the TestClass1. What you are doing is assign a new reference in the TestClass1 that is not bound to your DataContext.
Upvotes: 2
Reputation: 44068
You're assigning TestGrid.DataContext = TestClass1; Changing the object reference of the variable to a different object does not change the object reference in the DataContext property of the TestGrid. Take a look at the basics of OOP for more details
Edit: I mean, doing TestClass1 = new TestClass(); does not change the fact that the Datacontext of your grid is still the same object instance it was before.
Upvotes: 4