2017-02-27 54 views
1

我在我的視圖模型一個行動中的實體框架幹活添加記錄有一個動作在這樣的視圖來顯示記錄:INotifyPropertyChanged的不刷新列表視圖我在WPF MVVM實體

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 
    } 

這將在構建我的視圖模型時調用。因此,我的視圖中的列表視圖將顯示記錄。 我已經在我看來model..I一個添加記錄行動已經在對應於實體類生成例如性能我視圖模型創建的屬性:

 private String _FirstName; 
     public String FirstName 
     { 
     get 
     { 
      return _FirstName; 
     } 
     set 
     { 
      _FirstName = 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); 
     FillProspects(); 
     //RaisePropertyChanged("Prospects"); 
    } 

我繼承了:INotifyPropertyChanged和進口它的

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

但我的通知不刷新我的查看Listview記錄後添加記錄。因此,我只是在addrecord行動中調用填充記錄方法'FillProspects'。這是做MVVM的正確方法。爲什麼我的Listview沒有刷新後,添加記錄行動,我失蹤了?我有試圖與 RaisePropertyChanged("Prospects");在添加記錄動作......但它不是令人耳目一新。所以我只是叫補法再次行動

我的完整視圖模型:

  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)); } 
} 

}

我的觀點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> 

+0

如果您沒有將新記錄添加到集合中,您如何期望刷新控件? – 2017-02-27 09:23:42

回答

1

變化從List<Prospect>Prospects屬性來ObservableCollection<Prospect>類型:

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

並添加新的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); 
} 

只需將它添加到DbContext不影響ListView

+0

Observable集合對我來說是新的。 。我已經改變了你提到的代碼..但仍然無法正常工作..我已經從我的視圖模型完全刪除FillProspects()方法..現在甚至在表單加載列表視圖不顯示任何記錄..在添加方法插入DB中的記錄正在發生,但在此之後'Prospects.Add(newprospect);代碼顯示errror:空引用異常未處理 未將對象引用設置爲對象的實例。 – faisal

+0

在添加項目之前,您需要新建(創建)ObservableCollection的實例。我編輯了我的答案來澄清這一點。當然,您需要使用FillProspects方法從數據庫加載記錄,並最初填充集合。 – mm8

+0

它工作正常......但是,不會刷新數據庫中的值..所以我認爲在添加記錄後調用方法會更好。如果我錯了? – faisal

0

如果你要綁定以便在您的視圖模型集合,我建議使用一個ObservableCollection。
ObservableCollection實現INotifyCollectionChanged,它在添加或刪除元素時通知視圖。
有了這個,你不應該需要你的「FillProspects」方法和你的「RaisePropertyChanged(」Prospects「)」。

如果您想了解更多信息,我建議您發佈如何綁定到您的XAML中,以及如何構建您的「Prospects」對象(我們甚至不知道它是什麼類型,我只是假設它不是ObservableCollection) 。

編輯: 您將您的ListView綁定到「前景」,但在您的ViewModel中,我看到「前景」是類型「列表」,它需要是「ObservableCollection」。我看到你有一個名爲「前景」的ObservableCollection,但你不會在任何地方使用它。這可能是問題嗎?

+0

我使用了objservable集合: – faisal

+0

您是否正確設置了DataContext?你能否更新你的帖子以顯示你的「AddToProspects」方法以及你如何綁定到你的XAML中? – Tesseract

+0

我已經設置我的DataContext查看cs – faisal

1

這是好的新項目添加到數據庫,然後用同樣的刷新方法FillProspects再次檢索集合:

你在做什麼是基本正確。

+0

FillProspects方法的工作原理,但我預見到它的一些問題。爲每次刷新重新創建整個列表可能會導致視圖出現問題。所選項目在每次刷新時都會被取消選中,當您將鼠標懸停在項目上時會發生閃爍,甚至會導致性能問題(視圖在每次刷新時會凍結一點)。使用實現INotifyCollectionChanged的東西是通常的WPF方式。 – Tesseract

+0

@Tseseract這裏僅僅是一個關於[ObservableCollection]問題的例子(http://stackoverflow.com/questions/42528460/add-a-check-with-messagebox-when-datagrid-is-changed/)廣泛使用它 - *像我一樣* ...如果你有「*通常的WPF方式*」答案,隨時隨地跟進:)更一般地說,我會說從數據庫刷新新項目是一個更多*一致性和功能性*方法,比做兩個*獨立和順序* DB和查看更新(如在接受的答案) – 2017-03-01 17:24:36

+0

是的,我知道你的意思,我也使用ObservableCollection很多,它有一些很大的缺陷。但是,我試過(真的很難)從數據庫刷新整個事情,發現結果看起來不可接受。現在我主要更新數據庫中的Model&ViewModel,並讓Binding完成剩下的工作。 – Tesseract