ListBox binding with ViewModel in WPF

wpf

Solution

And for the correct binding in `ListBox.ItemTemplate`:

<TextBlock Text="{Binding FirstName}"
           FontWeight="Bold" Foreground="Navy"/>
<TextBlock Text="{Binding LastName}"
           FontWeight="Bold" Foreground="Navy"/>

The `DataContext` of `ListBoxItem` is a Customer already.

Problem

I am new to the WPF and trying to build a sample application using the MVVM framework. My application has a xaml file which has some textboxes for inputing customer info, combo box for display of states and a save button. All the databinding is done through ViewModel(CustomerViewMode) which has a reference to the Model(Customer), containing the required fields and their Getter, setters. The viewModel has a CustomerList property. On clicking the save button, I want to display the FirstName and LastName properties of Customer in a ListBox. This is where the problem is. I debugged the code, (Click event of button in the code behind), I can see that the CustomerList has the first Customer object with all its details, but its not getting displayed in the listbox. My code is: Customer(Model); ``` enter code here namespace SampleMVVM.Models { class Customer : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private String _firstName; private String _lastName; private Address _customerAddress; public String FirstName { get { return _firstName; } set { if (value != _firstName) { _firstName = value; RaisePropertyChanged("FirstName"); } } } public String LastName { get { return _lastName; } set { if (value != _lastName) { _lastName = value; RaisePropertyChanged("LastName"); } } } public Address CustomerAddress { get { return _customerAddress; } set { if (value != _customerAddress) { _customerAddress = value; RaisePropertyChanged("CustomerAddress"); } } } private void RaisePropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } } ``` } Address(Model) ``` namespace SampleMVVM.Models { class Address : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string _addressLine1; private string _addressLine2; private string _city; //private string _selectedState; private string _postalCode; private string _country; public String AddressLine1 { get { return _addressLine1; } set { if (value != _addressLine1) { _addressLine1 = value; RaisePropertyChanged(AddressLine1); } } } public String AddressLine2 { get { return _addressLine2; } set { if (value != _addressLine2) { _addressLine2 = value; RaisePropertyChanged(AddressLine2); } } } public String City { get { return _city; } set { if (value != _city) { _city = value; RaisePropertyChanged(City); } } } public String PostalCode { get { return _postalCode; } set { if (value != _postalCode) { _postalCode = value; RaisePropertyChanged(PostalCode); } } } public String Country { get { return _country; } set { if (value != _country) { _country = value; RaisePropertyChanged(Country); } } } private void RaisePropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } } ``` } CustomerViewModel: ``` namespace SampleMVVM.ViewModels { class CustomerViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private Customer _customer; RelayCommand _saveCommand; private List<String> _stateList = new List<string>(); private string _selectedState; private ObservableCollection<Customer> _customerList = new ObservableCollection<Customer>(); //public CustomerViewModel(ObservableCollection<Customer> customers) //{ // _customers = new ListCollectionView(customers); //} public Customer CustomerModel { get { return _customer; } set { if (value != _customer) { _customer = value; RaisePropertyChanged("CustomerModel"); } } } public List<String> StateList { get { return _stateList; } set { _stateList = value; } } public ObservableCollection<Customer> CustomerList { get { return _customerList; } set { if (value != _customerList) { _customerList = value; RaisePropertyChanged("CustomerList"); } } } public CustomerViewModel() { CustomerModel = new Customer { FirstName = "Fred", LastName = "Anders", CustomerAddress = new Address { AddressLine1 = "Northeastern University", AddressLine2 = "360, Huntington Avenue", City = "Boston", PostalCode = "02115", Country = "US", } }; StateList = new List<String> { "Alaska", "Arizona", "California", "Connecticut", "Massachusetts", "New Jersey", "Pennsylvania", "Texas" }; SelectedState = StateList.FirstOrDefault(); } public String SelectedState { get { return _selectedState; } set { if (value != _selectedState) { _selectedState = value; RaisePropertyChanged(SelectedState); } } } private void RaisePropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } } ``` } CustomerInfo.xaml(view) ``` <UserControl x:Class="SampleMVVM.Views.CustomerInfo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:ViewModels="clr-namespace:SampleMVVM.ViewModels" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <UserControl.DataContext> <ViewModels:CustomerViewModel /> </UserControl.DataContext> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <!--Starting label--> <TextBlock FontSize="18" FontFamily="Comic Sans MS" FontWeight="ExtraBlack" Foreground="Navy" Grid.Row="0" HorizontalAlignment="Center"> <TextBlock.Text> Customer Information: </TextBlock.Text> </TextBlock> <TextBlock Text="First name: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1" Width="80px" Height="50px" Margin="40,5,0,0"/> <TextBox Text="{Binding CustomerModel.FirstName}" Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0" Name="fname"/> <TextBlock Text="Last Name: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="2" Width="80px" Height="50px" Margin="40,5,0,0"/> <TextBox Text="{Binding CustomerModel.LastName}" Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="2" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0" Name="lname"/> <TextBlock Text="Address: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="3" Width="80px" Height="50px" Margin="40,5,0,0"/> <TextBox Text="{Binding CustomerModel.CustomerAddress.AddressLine1}" Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="3" Grid.Column="1" Width="160px" Height="20px" Margin="20,5,0,0"/> <TextBox Text="{Binding CustomerModel.CustomerAddress.AddressLine2}" Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="4" Grid.Column="1" Width="160px" Height="30px" Margin="20,5,0,0"/> <TextBlock Text="City: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="5" Width="80px" Height="20px" Margin="40,5,0,0"/> <TextBox Text="{Binding CustomerModel.CustomerAddress.City}" Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="5" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"/> <TextBlock Text="State: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="6" Width="80px" Height="20px" Margin="40,5,0,0"/> <ComboBox Grid.RowSpan="2" HorizontalAlignment="Left" Name="listOfSates" VerticalAlignment="Top" Grid.Row="6" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0" ItemsSource="{Binding Path=StateList}" SelectedItem="{Binding Path=SelectedState}" SelectionChanged="ComboBox_SelectionChanged" > </ComboBox> <TextBlock Text="PostalCode: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="7" Width="80px" Height="20px" Margin="40,5,0,0"/> <TextBox Text="{Binding CustomerModel.CustomerAddress.PostalCode}" Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="7" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"/> <TextBlock Text="Country: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="8" Width="80px" Height="20px" Margin="40,5,0,0"/> <TextBox Text="{Binding CustomerModel.CustomerAddress.Country}" Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="8" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"/> <Button Content="Save" Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="9" Width="50px" Height="20px" Name="savebtn" Margin="40,5,0,0" Click="savebtn_Click"/> <ListBox Name="cList" ItemsSource="{Binding Path=CustomerList}" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1" Grid.Column="2" Grid.RowSpan="2" Width="200px" Height="300px" Margin="200,5,0,0"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding CustomerModel.FirstName}" FontWeight="Bold" Foreground="Navy"/> <TextBlock Text=", " /> <TextBlock Text="{Binding CustomerModel.LastName}" FontWeight="Bold" Foreground="Navy"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> ``` CustomerInfo(Code behind class) ``` namespace SampleMVVM.Views { /// <summary> /// Interaction logic for CustomerInfo.xaml /// </summary> public partial class CustomerInfo : UserControl { public CustomerInfo() { InitializeComponent(); //checkvalue(); } private void savebtn_Click(object sender, RoutedEventArgs e) { ////Customer c = new Customer(); ////c.FirstName = fname.Text; ////c.LastName = lname.Text; //CustomerViewModel cvm = new CustomerViewModel(); //cvm.CustomerModel.FirstName = fname.Text; //cvm.CustomerModel.LastName = lname.Text; //List<CustomerViewModel> customerList = new List<CustomerViewModel>(); //customerList.Add(cvm); var viewModel = DataContext as CustomerViewModel; if (viewModel != null) { //viewModel.ShowCustomerInfo(); String strfname = viewModel.CustomerModel.FirstName; String strname = viewModel.CustomerModel.LastName; viewModel.CustomerList.Add(viewModel.CustomerModel); String str1 = viewModel.CustomerList.FirstOrDefault().FirstName; int i = viewModel.CustomerList.Count(); //cList.ItemsSource = viewModel.CustomerList; } } private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { CustomerViewModel cvm = new CustomerViewModel(); cvm.SelectedState = listOfSates.SelectedItem.ToString(); } } ``` } I just cant understand where am I going wrong...Someone please help

Original source

Related problems