I have a class called ViewModel that implements the INotifyPropertyChanged interface. In my XAML I have 3 textboxes that have a binding property that match my ViewModel properties:
TestsOrdered TestsCompleted TestsRemaining
I have a PropertyChanged event handler in my code-behind. I have a context "MyContext" attached to the XAML window. I am unsure why the UI does not update when I change the TestsOrdered and TestsCompleted values. I expect the UI to update when I tab out of the textboxes but does not until I tab out of the TestsRemaining textbox. Where is the flaw in my design ?
public partial class MainWindow : Window
{
public ViewModel vm;
public MainWindow()
{
InitializeComponent();
vm = new ViewModel();
//ct = new CompletionTime();
//ct.TestsOrdered = 8000;
vm.Name = "John Doe";
vm.TestsCompleted = 0;
vm.TestsOrdered = 0;
vm.TestsRemaining = 0;
this.MyContext.DataContext = vm;
}
private void btnName_Click(object sender, RoutedEventArgs e)
{
vm.Name = "Joe";
}
}
public class ViewModel : INotifyPropertyChanged
{
private string name;
private int mTestsOrdered;
private int mTestsRemaining;
private int mTestsCompleted;
public string Name
{
get { name; }
set
{
if (name != value)
{
name = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
}
}
public int TestsOrdered
{
get { return mTestsOrdered; }
set
{
if (mTestsOrdered != value)
{
mTestsOrdered = value;
PropertyChanged(this, new PropertyChangedEventArgs("TestsOrdered"));
}
}
}
public int TestsCompleted
{
get { return mTestsCompleted; }
set
{
if (mTestsCompleted != value)
{
mTestsCompleted = value;
PropertyChanged(this, new PropertyChangedEventArgs("TestsCompleted"));
}
}
}
public int TestsRemaining
{
get { return TestsOrdered - TestsCompleted; }
set
{
if (mTestsRemaining != value)
{
mTestsRemaining = value;
PropertyChanged(this, new PropertyChangedEventArgs("TestsRemaining"));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
MyContext is the DataContext that holds a ViewModel object.
XAML:
<Grid Margin="-1,-9,1,9">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="244*"/>
<ColumnDefinition Width="251*"/>
</Grid.ColumnDefinitions>
<TextBox Width="100" HorizontalAlignment="Center" Margin="96.791,40,54,0" TextWrapping="Wrap" Text="{Binding Path=Name}" VerticalAlignment="Top" Grid.Column="1"/>
<Button x:Name="btnName" Content="Button" HorizontalAlignment="Left" Margin="171,210,0,0" VerticalAlignment="Top" Width="148" Height="47" Click="btnName_Click" Grid.ColumnSpan="2"/>
<TextBox Grid.Column="0" HorizontalAlignment="Left" Height="23" Margin="97,84,0,0" TextWrapping="Wrap" Text="{Binding Path=TestsOrdered}" VerticalAlignment="Top" Width="120"/>
<TextBox Grid.Column="0" HorizontalAlignment="Left" Height="23" Margin="97,112,0,0" TextWrapping="Wrap" Text="{Binding Path=TestsCompleted}" VerticalAlignment="Top" Width="120"/>
<TextBox Grid.Column="0" HorizontalAlignment="Left" Height="23" Margin="97,140,0,0" TextWrapping="Wrap" Text="{Binding Path=TestsRemaining}" VerticalAlignment="Top" Width="120"/>
</Grid>
MyContext
? – AndersBinding
class uses theWindow
property:DataContext
as it's default object to bind to. You could say that the full path of your bindings are<WindowInstance>.DataContext.<PathDefinded>
. The Solution is to set your view model instance on the propertyDataContext
. I'll write a answer to you. – Anders