简体   繁体   English

INotifyPropertyChanged未刷新WPF MVVM实体中的列表视图

[英]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 我继承了: INotifyPropertyChanged并将其导入

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"); 但是我的通知没有在添加记录后刷新我的视图Listview记录。所以我只是在addrecord操作中调用填充记录方法“ FillProspects”。这是执行MVVM的正确方法。为什么我的Listview在添加记录操作后没有得到刷新我想念的地方?我尝试过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: 我的看法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 : 可以将新项目添加到数据库,然后使用相同的刷新方法FillProspects再次检索集合:

what you're doing is basically correct. 您所做的基本上是正确的。

Change the type of the Prospects property from List<Prospect> to ObservableCollection<Prospect> : Prospects属性的类型从List<Prospect>更改为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: 并在您的Add1方法中将新的Prospect对象添加到此集合中:

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 . 仅将其添加到DbContext不会影响ListView

If you're going to bind a view to a collection in your ViewModel, I suggest using an ObservableCollection. 如果要将视图绑定到ViewModel中的集合,则建议使用ObservableCollection。
The ObservableCollection implements INotifyCollectionChanged, it notifies the view when elements are added or removed. ObservableCollection实现INotifyCollectionChanged,它在添加或删除元素时通知视图。
With this you should not need your "FillProspects" method and your "RaisePropertyChanged("Prospects")". 这样,您就不需要“ FillProspects”方法和“ 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). 如果您想了解更多信息,建议您发布如何绑定到XAML中以及如何构造“前景”对象(我们甚至不知道它是什么类型,我只是假设它不是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". 编辑:您将ListView绑定到“前景”,但是在您的ViewModel中,我看到“前景”的类型为“列表”,它需要为“ ObservableCollection”。 I see that you have an ObservableCollection named "prospects", but you don't use it anywhere. 我看到您有一个名为“ prospects”的ObservableCollection,但是您没有在任何地方使用它。 Could this be the issue ? 这可能是问题吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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