xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns:d='http://schemas.microsoft.com/expression/blend/2008' xmlns:mc='http://schemas.openxmlformats.org/markup-compatibility/2006' mc:Ignorable='d' d:DesignWidth='640' d:DesignHeight='480' xmlns:local="clr-namespace:SilverlightApplication3"> Grid.Row="0" HorizontalAlignment="Stretch"/> Text="Error" Foreground="Black" HorizontalAlignment="Center"/> TextWrapping="Wrap" HorizontalAlignment="Stretch"/> ItemsSource="{StaticResource REF_EmployeeCollection}" SelectionChanged="lbx_Employees_SelectionChanged" /> ValidatesOnExceptions=True,NotifyOnValidationError=True}" BindingValidationError="TextBox_BindingValidationError" x:Name="State"> x:Name="State_TooltipContent"/> BindingValidationError="TextBox_BindingValidationError" x:Name="ZipCode"/> HorizontalAlignment="Stretch" VerticalAlignment="Stretch" > ValidatesOnExceptions=True,NotifyOnValidationError=True}" BindingValidationError="TextBox_BindingValidationError" x:Name="PhoneNum"/> x:Name="PhoneNum_TooltipContent"/> //File: Page.xaml.cs using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; namespace SilverlightApplication3 { public class Employee : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(PropertyChangedEventArgs e) { if (PropertyChanged != null) PropertyChanged(this, e); } public Employee() { } private string _FirstName; public string FirstName { get { return _FirstName; } set { string OldVal = _FirstName; if (OldVal != value) { _FirstName = value; RaisePropertyChanged(new PropertyChangedEventArgs("FirstName")); } } } private string _LastName; public string LastName { get { return _LastName; } set { string OldVal = _LastName; if (OldVal != value) { _LastName = value; RaisePropertyChanged(new PropertyChangedEventArgs("LastName")); } } } private long _PhoneNum; public long PhoneNum { get { return _PhoneNum; } set { long OldVal = _PhoneNum; if (value.ToString().Length != 10) throw new Exception("Phone Number has to be exactly 10 digits"); if (OldVal != value) { _PhoneNum = value; RaisePropertyChanged(new PropertyChangedEventArgs("PhoneNum")); } } } private Address _Address; public Address Address { get { return _Address; } set { Address OldVal = _Address; if (OldVal != value) { _Address = value; RaisePropertyChanged(new PropertyChangedEventArgs("Address")); } } } } public class Address : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(PropertyChangedEventArgs e) { if (PropertyChanged != null) PropertyChanged(this, e); } private string _Street; public string Street { get { return _Street; } set { string OldVal = _Street; if (OldVal != value) { _Street = value; RaisePropertyChanged(new PropertyChangedEventArgs("Street")); } } } private string _City; public string City { get { return _City; } set { string OldVal = _City; if (OldVal != value) { _City = value; RaisePropertyChanged(new PropertyChangedEventArgs("City")); } } } private string _State; public string State { get { return _State; } set { string OldVal = _State; if (value.Length != 2) throw new Exception("State needs to be the 2 letter abbreviation for the US State"); if (OldVal != value) { _State = value; RaisePropertyChanged(new PropertyChangedEventArgs("State")); } } } private int _ZipCode; public int ZipCode { get { return _ZipCode; } set { int OldVal = _ZipCode; if (value.ToString().Length != 5) throw new Exception("Zipcode needs to be exactly 5 digits"); if (OldVal != value) { _ZipCode = value; RaisePropertyChanged(new PropertyChangedEventArgs("ZipCode")); } } } } public class EmployeeCollection : ICollection, IList, INotifyCollectionChanged { private List _internalList; public EmployeeCollection(){ _internalList = new List(); } public event NotifyCollectionChangedEventHandler CollectionChanged; private void RaiseCollectionChanged(NotifyCollectionChangedEventArgs e) { if (CollectionChanged != null) { CollectionChanged(this, e); } } public void Add(Employee item) { _internalList.Add(item); RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,item, _internalList.Count - 1)); } public void Clear() { _internalList.Clear(); RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } public bool Remove(Employee item) { int idx = _internalList.IndexOf(item); bool RetVal = _internalList.Remove(item); if (RetVal) RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,item, idx)); return RetVal; } public void RemoveAt(int index) { Employee item = null; if (index < _internalList.Count) item = _internalList[index]; _internalList.RemoveAt(index); if (index < _internalList.Count) RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,item, index)); } public void Insert(int index, Employee item) { _internalList.Insert(index, item); RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,item, index)); } public Employee this[int index] { get { return _internalList[index]; } set { _internalList[index] = value; RaiseCollectionChanged( new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, index)); } } public bool Contains(Employee item) { return _internalList.Contains(item); } public void CopyTo(Employee[] array, int arrayIndex) { _internalList.CopyTo(array, arrayIndex); } public int Count { get { return _internalList.Count; } } public bool IsReadOnly { get { return ((IList)_internalList).IsReadOnly; } } public IEnumerator GetEnumerator() { return _internalList.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return (System.Collections.IEnumerator)_internalList.GetEnumerator(); } public int IndexOf(Employee item) { return _internalList.IndexOf(item); } } public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); EmployeeCollection empColl = (EmployeeCollection)lbx_Employees.ItemsSource; empColl.Add(new Employee { FirstName = "A", LastName = "B", PhoneNum = 2, Address = new Address { Street = "2 Street", City = "New York", State = "NY", ZipCode = 10006 } }); empColl.Add(new Employee { FirstName = "A", LastName = "B", PhoneNum = 7, Address = new Address { Street = "1 Street", City = "New York", State = "NY", ZipCode = 10007 } }); empColl.Add(new Employee { FirstName = "N", LastName = "M", PhoneNum = 7, Address = new Address { Street = "1 Road", City = "New York", State = "NY", ZipCode = 10016 } }); } private void btn_New_Click(object sender, RoutedEventArgs e) { EmployeeCollection empColl = (EmployeeCollection)lbx_Employees.ItemsSource; Employee newEmp = new Employee(); newEmp.Address = new Address(); empColl.Add(newEmp); lbx_Employees.SelectedItem = newEmp; } private void lbx_Employees_SelectionChanged(object sender,SelectionChangedEventArgs e) { grid_EmployeeForm.DataContext = (Employee)lbx_Employees.SelectedItem; grid_EmployeeForm.Visibility = Visibility.Visible; } private void btnClose_Click(object sender, RoutedEventArgs e) { grid_EmployeeForm.Visibility = Visibility.Collapsed; } private void TextBox_BindingValidationError(object sender, ValidationErrorEventArgs e) { if (e.Action == ValidationErrorEventAction.Added) { if (sender is TextBox) { (sender as TextBox).Background = new SolidColorBrush(Colors.Red); } else if (sender is Grid) { TextBlock errorInd = (sender as Grid).FindName((e.OriginalSource as TextBox).Name + "_ErrorIndicator") as TextBlock; errorInd.Visibility = Visibility.Visible; errorInd.Text = "*"; ContentControl tooltipContent = errorInd.FindName((e.OriginalSource as TextBox).Name + "_TooltipContent") as ContentControl; tooltipContent.Content = e.Error.Exception.Message; } } else { if (sender is TextBox) { (sender as TextBox).Background = new SolidColorBrush(Colors.Transparent); } else if (sender is Grid) { ((sender as Grid).FindName((e.OriginalSource as TextBox).Name + "_ErrorIndicator") as TextBlock).Visibility = Visibility.Collapsed; ; } } } } }