简体   繁体   中英

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>

It is fine to add the new item to the DB and then retrieve again the collection with the same refresh method FillProspects :

what you're doing is basically correct.

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 .

If you're going to bind a view to a collection in your ViewModel, I suggest using an ObservableCollection.
The ObservableCollection implements INotifyCollectionChanged, it notifies the view when elements are added or removed.
With this you should not need your "FillProspects" method and your "RaisePropertyChanged("Prospects")".

If you want more information I suggest posting how you bind in your XAML and also how you construct your "Prospects" object (we don't even know what type it is, I just assume it isn't an ObservableCollection).

EDIT : you bind your ListView to "Prospects", but in your ViewModel, I see that "Prospects" is of type "List", it needs to be "ObservableCollection". I see that you have an ObservableCollection named "prospects", but you don't use it anywhere. Could this be the issue ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM