2017-02-27 4 views
1

Ich habe eine Aktion in meiner Ansicht nach Modell Rekord in Entity-Rahmen work.I hinzuzufügen haben eine Aktion, um die Datensätze in der Ansicht wie folgt angezeigt:INotifyPropertyChanged ist erfrischend, nicht meine Listview in WPF MVVM Entität

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 
    } 

Dies wird in der Konstruktion meines View-Modells aufgerufen. Als Ergebnis zeigt die Listenansicht in meiner Ansicht die Datensätze an. Ich habe eine Add Rekord Aktion in meiner Ansicht model..I geschaffen Eigenschaften meiner Meinung nach Modell in der Entity-Klasse zum Beispiel Eigenschaften erzeugt entsprechen:

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

     } 
    } 

Und meine Add Rekord Aktion in der Ansicht Modell ist:

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

ich habe die geerbte: INotifyPropertyChanged und importiert es

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

Aber meine Benachrichtigung erfrischend ist nicht meine view Listview Datensätze nach dem Hinzufügen von Datensatz .so Ich nenne nur die Fülle Datensätze Methode "FillProspects" in der Aktion addrecord..Ist das richtige Weg MVVM zu tun. Warum wird meine Listview nicht nach Datensatz hinzufügen Aktion, wo ich vermisse? Ich habe versucht, mit RaisePropertyChanged("Prospects"); im Add Rekord Aktion ... aber es ist nicht .So erfrischend ich nur Fill-Methode Aktion aufgerufen wieder

Meine komplette Ansicht Modell:

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

}

Meine Ansicht 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

Wenn Sie den neuen Datensatz nicht zur Sammlung hinzufügen, wie können Sie eine Aktualisierung des Steuerelements erwarten? –

Antwort

1

ändern Sie den Typ der Prospects Eigenschaft List<Prospect>-ObservableCollection<Prospect>:

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

Und das neue Prospect Objekt zu dieser Sammlung auch in Ihrer Add1 Methode:

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

Nur Zugabe zu Die DbContext hat keinen Einfluss auf die ListView.

+0

Observable collections ist neu für mich .. .Ich habe den Code geändert, wie Sie erwähnt..aber immer noch nicht funktioniert..Ich habe die FillProspects() -Methode aus meinem Ansichtsmodell vollständig entfernt .. Jetzt auch in Formular laden Listenansicht zeigt keine Datensätze..In add Methode einzufügen die Aufzeichnungen in der DB passiert, aber danach 'Prospects.Add (newprospect); Code zeigt Fehler an: Nullreferenz Ausnahme wurde nicht behandelt Objektverweis nicht auf eine Instanz eines Objekts festgelegt. – faisal

+0

Sie müssen die ObservableCollection neu erstellen (eine Instanz erstellen), bevor Sie ihr Objekte hinzufügen. Ich habe meine Antwort bearbeitet, um dies zu klären. Und natürlich müssen Sie die Methode FillProspects verwenden, um die Datensätze aus der Datenbank zu laden und die Sammlung zu initialisieren. – mm8

+0

es funktioniert gut ... aber inotifcation wird nicht den Wert aus der Datenbank aktualisieren ... Also ich denke, es wird besser sein, Methode nach dem Hinzufügen der Aufzeichnung aufzurufen. Wenn ich falsch liege? – faisal

0

Wenn Sie einen Blick auf eine Sammlung in Ihrem Ansichtsmodell binden werden, ich schlage vor, mit einer ObservableCollection.
Die ObservableCollection implementiert INotifyCollectionChanged, sie benachrichtigt die Ansicht, wenn Elemente hinzugefügt oder entfernt werden.
Mit diesem sollten Sie nicht Ihre "FillProspects" -Methode und Ihre "RaisePropertyChanged (" Prospects ") benötigen."

Wenn Sie weitere Informationen wünschen, schlage ich vor, wie Sie in Ihrem XAML binden und wie Sie Ihr "Prospects" -Objekt konstruieren (wir wissen nicht einmal, welcher Typ es ist, ich nehme einfach an, dass es keine ObservableCollection ist) .
EDIT: binden Sie Ihre ListView zu "Prospects", aber in Ihrem ViewModel sehe ich, dass "Prospects" vom Typ "List" ist, muss es "ObservableCollection" sein. Ich sehe, dass Sie eine ObservableCollection mit dem Namen "potentials" haben, aber Sie verwenden sie nirgends. Könnte das das Problem sein?

+0

Ich habe objservable Sammlung verwendet: – faisal

+0

Haben Sie Ihren DataContext richtig eingestellt? Können Sie Ihren Post aktualisieren, um Ihre "AddToProspects" -Methode anzuzeigen und wie Sie in Ihrem XAML binden? – Tesseract

+0

Ich habe meinen DataContext in der Seite Einstellungen von View cs – faisal

1

Es ist in Ordnung, das neue Element der DB und dann abrufen wieder die Sammlung mit der gleichen Aktualisierungsmethode FillProspects hinzuzufügen:

, was Sie tun, ist grundsätzlich richtig.

+0

Die FillProspects-Methode funktioniert, aber ich sehe einige Probleme damit. Das erneute Erstellen der gesamten Liste für jede Aktualisierung kann zu Problemen mit der Ansicht führen. Ausgewählte Elemente werden bei jeder Aktualisierung nicht ausgewählt. Wenn Sie den Mauszeiger über Elemente bewegen, kann es zu Flackern kommen. Dies kann sogar zu Leistungsproblemen führen (die Ansicht bleibt bei jeder Aktualisierung ein wenig stehen). Das Verwenden von etwas, das INotifyCollectionChanged implementiert, ist der übliche WPF-Weg. – Tesseract

+0

@Tesseract hier ist nur ein Beispiel über die [Probleme mit ObservableCollection] (http://stackoverflow.com/questions/42528460/add-a-check-with-messagebox-when-datagrid-is-changed/), wenn man startet Verwenden Sie es ausgiebig - * wie ich * ... fühlen Sie sich frei, dort zu folgen, wenn Sie die "* übliche WPF-way *" Antwort haben :) Allgemein würde ich sagen, dass das Aktualisieren der neuen Elemente aus der DB ist mehr * konsequente und funktionale * Ansatz, als zwei * separate und sequentielle * DB tun und Updates anzeigen (wie in der angenommenen Antwort) –

+0

Ja, ich weiß was du meinst, ich benutze ObservableCollection auch viel und es hat einige große Fehler. Allerdings habe ich (wirklich schwer) versucht, das Ganze von DB aufzufrischen und fand heraus, dass die Ergebnisse visuell inakzeptabel waren. Jetzt aktualisiere ich meistens mein Model & ViewModel aus der DB und lass Binding den Rest erledigen. – Tesseract