Search code examples
c#wpfentity-frameworkentity-framework-4

INotifyPropertyChanged is not refreshing my listview in WPF MVVM entity


I have one action in my view model to add record in to entity frame work.I have one action to display the records in the view like this :

    private void FillProspects()

    {
        var q = (from a in ctx2.Prospects// 'ctx' is the object of entity 
                 select a).ToList();
        this.Prospects = q;               // 'Porspects' is a collection of   entity class this I have bound with my List view in my view
    }

This will be called in construction of my view model.as a result the list view in my view will be showing the records . I have one add record action in my view model..I have created properties in my view model corresponding to properties generated in the entity class for example:

      private String _FirstName;
      public String FirstName
      {
         get
        {
             return _FirstName;
        }
        set
        {
            _FirstName = value;

        }
     }

And my add record action in the view model is :

    public void Add1()
    {
        newprospect = new Prospect();
        newprospect.ID = Guid.NewGuid();
        newprospect.FirstName = FirstName;
        newprospect.LastName = LastName;
        newprospect.Address = Address;
        newprospect.State = State;
        newprospect.City = City;
        newprospect.ZIP = ZIP;
        prospect = newprospect;
        ctx2.AddToProspects(prospect);
        FillProspects();
        //RaisePropertyChanged("Prospects");
    }

I have inherited the : INotifyPropertyChanged and imported it's

using System.Windows.Input; 
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private void RaisePropertyChanged(string property) { PropertyChanged(this, new PropertyChangedEventArgs(property)); }

But my notification is not refreshing my view Listview records after adding record .so I just call the fill records method 'FillProspects' in the addrecord action..Is this right way of doing MVVM .Why my Listview is not getting refreshed after add record action where I am missing?I have tried with RaisePropertyChanged("Prospects");in the Add record action...but it is not refreshing .So I just called fill method action again

My complete view model:

           using System;
       using System.Collections.Generic;
       using System.Linq;
     using System.Text;
      using System.ComponentModel;
     using System.Windows.Input;
     using System.Collections.ObjectModel;

     namespace Wpfentity3
  {
public class frmProspects_VM : INotifyPropertyChanged
{
    TestsEntities ctx2 = new TestsEntities();
    public ObservableCollection<Prospect> prospects { get; set; }
    //This is the collection where records - er, entities - returned by a query are stored; 
    //Prospect is the generated class that defines a record - er,
    //an entity as well as the query for that table.

    private CommandMap _Commands;
    public CommandMap Commands { get { return _Commands; } }   

    Prospect newprospect;
    //This holds a new prospect that is created and then added to the prospects collection
    private Prospect _prospect;
    public Prospect prospect {
                                 get
                                 { 
                                     return _prospect;
                                 } 
                                 set 
                                 { 
                                     _prospect = value;
                                     RaisePropertyChanged("prospect");
                                 }
                              }

    //prospect is the object that holds the current record from the Prospects table.
    //MainWindow  controls are bound to this object


    public frmProspects_VM()
    {
        //FillProspects();
        ctx2 = new TestsEntities();
        //This instantiates the EntityManager class  ;
        prospects = new ObservableCollection<Prospect>();
        //This instantiates the prospects collection of Prospect records - er, entities;

        _Commands = new CommandMap();
        _Commands.AddCommand("Add", x => Add1());
    }

    private ObservableCollection<Prospect> _prospects;
    public ObservableCollection<Prospect> Prospects
   {
      get
      {
        return _prospects;
      }
      set
     {
        _prospects = value;
        RaisePropertyChanged("Prospects");
      }
  }

    private String _FirstName;
    public String FirstName
    {
        get
        {
            return _FirstName;
        }
        set
        {
            _FirstName = value;

        }
    }
    private String _LastName;
    public String LastName
    {
        get
        {
            return _LastName;
        }
        set
        {
            _LastName = value;

        }
    }
    private String _Address;
    public String Address
    {
        get
        {
            return _Address;
        }
        set
        {
            _Address = value;

        }
    }

    private String _State;
    public String State
    {
        get
        {
            return _State;
        }
        set
        {
            _State = value;

        }
    }

    private String _City;
    public String City
    {
        get
        {
            return _City;
        }
        set
        {
            _City = value;

        }
    }
    private String _ZIP;
    public String ZIP
    {
        get
        {
            return _ZIP;
        }
        set
        {
            _ZIP = value;

        }
    }

       public void Add1()
  {

    newprospect = new Prospect();
    newprospect.ID = Guid.NewGuid();
    newprospect.FirstName = FirstName;
    newprospect.LastName = LastName;
    newprospect.Address = Address;
    newprospect.State = State;
    newprospect.City = City;
    newprospect.ZIP = ZIP;

    prospect = newprospect;
    ctx2.AddToProspects(prospect);
    Prospects.Add(newprospect);
    }

   public event PropertyChangedEventHandler PropertyChanged = delegate { };
   private void RaisePropertyChanged(string property) { PropertyChanged(this, new PropertyChangedEventArgs(property)); }
}

}

My view xamal:

    <Window x:Class="Wpfentity3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 WindowStartupLocation="CenterScreen"

   Title="Prospects"
   Height="482" Width="500" MaxWidth="500" MaxHeight="600"
   xmlns:cusns="clr-namespace:Wpfentity3">



    <StackPanel Height="290" VerticalAlignment="Top">
    <StackPanel Orientation="Horizontal" >
        <Label
    Content="Prospects"
    BorderBrush="Blue" BorderThickness="1"
    HorizontalAlignment="Left" VerticalAlignment="Top"
    FontSize="24" FontFamily="Comic Sans MS"
    Padding="13,3,13,9" Margin="5"
       Foreground="Purple" Background="LemonChiffon" />
          <Label 
   Content="{Binding Path=label}" Foreground="Red" FontSize="14"
   HorizontalAlignment="Right" VerticalAlignment="Center" 
   Height="auto" Margin="180,0,10,0" />


    </StackPanel>

    <Grid
  HorizontalAlignment="Left" VerticalAlignment="Top"
  Height="120" Width="475" >
        <Grid.RowDefinitions>
            <RowDefinition Height="25*" />
            <RowDefinition Height="25*" />
            <RowDefinition Height="25*" />
            <RowDefinition Height="25*" />

        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="90*" />
            <ColumnDefinition Width="135*" />
            <ColumnDefinition Width="45*" />
            <ColumnDefinition Width="32*" />
            <ColumnDefinition Width="57*" />
            <ColumnDefinition Width="118*" />
        </Grid.ColumnDefinitions>

        <Label
    Content="First name"
    Grid.Row="0" Grid.Column="0" Margin="0,0,5,0"
    HorizontalAlignment="Right" VerticalAlignment="Center" />
        <TextBox Name="txtFirstName" 
    Grid.Column="1"
    HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding Path=FirstName}" 
    Width="130" />

        <Label
    Content="Last name"
    Grid.Row="1" Grid.Column="0" Margin="0,0,5,0"
    HorizontalAlignment="Right" VerticalAlignment="Center" />
        <TextBox  Name="txtLastName"
    Grid.Row="1" Grid.Column="1"
    HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding LastName}"
    Width="130" />

        <Label
    Content="Address"
    Grid.Row="2" Grid.Column="0" Margin="0,0,5,0"
    HorizontalAlignment="Right" VerticalAlignment="Center" />
        <TextBox  Name="txtAddress"
    Grid.Row="2" Grid.Column="1"
    HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding Address}"
    Width="300" Grid.ColumnSpan="5" />

        <Label
    Content="City"
    Grid.Row="3" Grid.Column="0" Margin="0,0,5,0"
    HorizontalAlignment="Right" VerticalAlignment="Center" />
        <TextBox Name="txtCity"
    Grid.Row="3" Grid.Column="1"
    HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding City}"
    Width="130" />

        <Label
    Content="State"
    Grid.Row="3" Grid.Column="2" Margin="0,0,5,0"
    HorizontalAlignment="Right" VerticalAlignment="Center" />
        <TextBox Name="txtState"
    Grid.Row="3" Grid.Column="3" Width="30" MaxLength="2" CharacterCasing="Upper" Text="{Binding State}"
    HorizontalAlignment="Left" VerticalAlignment="Center" />

        <Label
       Content="ZIP code"
    Grid.Row="3" Grid.Column="4" Margin="0,0,5,0"
    HorizontalAlignment="Right" VerticalAlignment="Center" />
        <TextBox Name="txtZIP"
    Grid.Row="3" Grid.Column="5" MaxLength="10"
    HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding ZIP}"
    Width="90" />

    </Grid>

    <StackPanel Orientation="Horizontal" Margin="0,10,0,0">

        <Button Name="btnFind"
    Content="_Find"
    Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
        <Button Name="btnAdd"
    Content="_Add"  Command="{Binding Commands.Add}"
    Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
        <Button Name="btnEdit"
    Content="_Edit"
    Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
        <Button Name="btnDelete"
    Content="_Delete"
    Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
        <Button Name="btnSave"
    Content="_Save"
    Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
        <Button Name="btnCancel"
    Content="_Cancel"
    Width="auto" Margin="5,0,5,0" Padding="10,0,10,0" />
        <Button Name="btnClose"
    Content="Cl_ose"
    Width="auto" Margin="5,0,5,0" Padding="10,0,10,0"
    />



    </StackPanel>

    <StackPanel Height="34" Margin="10">
        <Grid Margin="10">
            <ListView Name="lvprospects" ItemsSource="{Binding Prospects}" Margin="0,0,0,-200">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="FirstName" Width="120" DisplayMemberBinding="{Binding  FirstName}" />
                        <GridViewColumn Header="LastName" Width="50" DisplayMemberBinding="{Binding LastName}" />
                        <GridViewColumn Header="Address" Width="50" DisplayMemberBinding="{Binding Address}" />
                        <GridViewColumn Header="City" Width="50" DisplayMemberBinding="{Binding City}" />
                        <GridViewColumn Header="State" Width="50" DisplayMemberBinding="{Binding State}" />
                        <GridViewColumn Header="ZIP" Width="50" DisplayMemberBinding="{Binding ZIP}" />
                    </GridView>
                </ListView.View>
            </ListView>
        </Grid>




    </StackPanel>

</StackPanel>


Solution

  • Change the type of the Prospects property from List<Prospect> to ObservableCollection<Prospect>:

    private ObservableCollection<Prospect> _prospects = new ObservableCollection<Prospect>();
    public ObservableCollection<Prospect> Prospects
    {
        get
        {
            return _prospects;
        }
        set
        {
            _prospects = value;
            RaisePropertyChanged("Prospects");
        }
    }
    

    And add the new Prospect object to this collection as well in your Add1 method:

    public void Add1()
    {
    
        newprospect = new Prospect();
        newprospect.ID = Guid.NewGuid();
        newprospect.FirstName = FirstName;
        newprospect.LastName = LastName;
        newprospect.Address = Address;
        newprospect.State = State;
        newprospect.City = City;
        newprospect.ZIP = ZIP;
    
        prospect = newprospect;
        ctx2.AddToProspects(prospect);
        Prospects.Add(newprospect);
    }
    

    Just adding it to the DbContext doesn't affect the ListView.