I finally got a Silverlight MVVM example to work so that when I change the values of first name and last name text boxes, the full names change automatically.
However, and strangely, my model which inherits from INotifyPropertyChanged is only notified if I change at least 2 characters of either the first or last name.
- if I change "Smith" to "Smith1", then no event is fired
- if I change "Smith" to "Smith12" then the event is fired, as expected
Has anyone run in to this before in Silverlight/XAML/INotifyPropertyChanged? What could it be? Is there a setting somewhere that indicates how much of a textbox needs to change before it notifies itself as "changed"?
Here are the main parts of the code I'm using:
Customer.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace TestMvvm345.Model
{
public class Customer : INotifyPropertyChanged
{
public int ID { get; set; }
public int NumberOfContracts { get; set; }
private string firstName;
private string lastName;
public string FirstName
{
get { return firstName; }
set
{
firstName = value;
RaisePropertyChanged("FirstName");
RaisePropertyChanged("FullName");
}
}
public string LastName
{
get { return lastName; }
set
{
lastName = value;
RaisePropertyChanged("LastName");
RaisePropertyChanged("FullName");
}
}
public string FullName
{
get { return firstName + " " + lastName; }
}
#region INotify
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
#endregion
}
}
CustomerHeaderView.xaml:
<UserControl x:Class="TestMvvm345.Views.CustomerHeaderView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel HorizontalAlignment="Left">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox x:Name="FirstName"
Text="{Binding Path=FirstName, Mode=TwoWay}"
Width="150"
Margin="3 5 3 5"/>
<TextBox x:Name="LastName"
Text="{Binding Path=LastName, Mode=TwoWay}"
Width="150"
Margin="0 5 3 5"/>
<TextBlock x:Name="FullName"
Text="{Binding Path=FullName, Mode=TwoWay}"
Margin="0 5 3 5"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</UserControl>
CustomerViewModel.cs:
using System.ComponentModel;
using System.Collections.ObjectModel;
using TestMvvm345.Model;
namespace TestMvvm345
{
public class CustomerViewModel
{
public ObservableCollection<Customer> Customers { get; set; }
public void LoadCustomers()
{
ObservableCollection<Customer> customers = new ObservableCollection<Customer>();
//this is where you would actually call your service
customers.Add(new Customer { FirstName = "Jim", LastName = "Smith", NumberOfContracts = 23 });
customers.Add(new Customer { FirstName = "Jane", LastName = "Smith", NumberOfContracts = 22 });
customers.Add(new Customer { FirstName = "John", LastName = "Tester", NumberOfContracts = 33 });
customers.Add(new Customer { FirstName = "Robert", LastName = "Smith", NumberOfContracts = 2 });
customers.Add(new Customer { FirstName = "Hank", LastName = "Jobs", NumberOfContracts = 5 });
Customers = customers;
}
}
}
MainPage.xaml.cs:
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
CustomerViewModel customerViewModel = new CustomerViewModel();
customerViewModel.LoadCustomers();
CustomerHeaderView.DataContext = customerViewModel.Customers;
}
UPDATE:
I remade this project in WPF and it works fine. Perhaps it's a Silverlight 3 issue.