2009-05-30 27 views
21

Ich habe ein WPF DataGrid mit einigen Daten. Sie können Zeilen durch ein separates Fenster hinzufügen. Der DataContext ist derselbe, ein LINQ-to-SQL-Objekt. Die Bindung ist auch die gleiche, ich binde die Eigenschaft "ItemsSource" an eine Tabelle.Wie wird ein WPF DataGrid aktualisiert?

In dem anderen Fenster, wenn der Benutzer auf "Speichern" klickt, erstelle ich eine Zeile programmatisch und füge sie mit "InsertOnSubmit" hinzu. Danach benutze ich die Methode "SubmitChanges" von DataContext.

Mein Problem ist, dass das DataGrid nicht aktualisiert wird. Wenn ich die Anwendung neu starte, kann ich die neue Zeile sehen, also befindet sie sich in der Datenbank, aber ich konnte keinen Weg finden, das DataGrid zu aktualisieren.

Bis jetzt habe ich versucht, "UpdateTarget" auf der BindingExpression des DataGrid zu verwenden, aber es hat nicht geholfen. Ich habe auch versucht "dataGrid.Items.Refresh()" - das gleiche Ergebnis. Wie kann ich das beheben?

Antwort

20

Der Grund dafür ist, dass LINQ-to-SQL INotifyCollectionChanged nicht implementiert, sodass WPF nicht feststellen kann, dass die ItemsSource aktualisiert wurde. Der am wenigsten erschreckende Weg, dies zu beheben, besteht darin, Ihre LINQ-to-SQL-Ergebnisse in eine ObservableCollection zu kopieren. Wenn Sie die Insert-Operation ausführen, fügen Sie sie ebenfalls der Observable-Auflistung hinzu. Dann sehen Sie das Update.

+0

Ihre Lösung funktioniert offensichtlich. Ich dachte nur, ich könnte mit einem einfachen XAML-Binding-Markup davonkommen. – KovBal

+0

Wenn wir eine ObservableCollection als eine Brücke zwischen linq zu sql und dem Steuerelement verwenden, wie können wir SubmitChanges() verwenden, um das Ergebnis zurück an die Datenbank zu senden? – MemoryLeak

+3

@MemoryLeak - also hier ist das knifflige bisschen; Sie möchten nicht nur wissen, wann sich die * Sammlung * ändert (d. h. was INotifyCollectionChanged), Sie möchten auch wissen, wann sich eines der * Elemente * ändert. Sie müssen also den Sammlungswechsel abonnieren und dann bei "Hinzufügen/Entfernen" den Eintrag "InotifyPropertyChanged" jedes Elements abonnieren. * Dann * müssen Sie entscheiden, was Sie speichern möchten, basierend darauf, welche Benachrichtigungen Sie erhalten. –

2

Das Problem besteht darin, dass Sie Ihren LINQ-to-SQL-DataContext aktualisieren müssen. Der DataContext erkennt die neue Zeile auch dann nicht ordnungsgemäß, wenn sich eine Übergabe ändert. Sie müssen den vorhandenen DataContext ablegen und einen neuen anlegen. In den meisten Fällen sollte DataContext für eine kurze Operation und nicht als ein langjähriges Objekt verwendet werden.

+0

Ihre Lösung ist der von Pwninstein sehr ähnlich. Leider ist das Ergebnis dasselbe, da das DataContextChanged-Ereignis das DataGrid nicht aktualisiert. – KovBal

0

Oder rufen Sie einfach den Suchcode erneut auf (normalerweise die Suchschaltfläche)> Ich habe es in meinem Fall so gelöst.

1

Wenn Sie einen Fall haben, wenn Sie ein Gitter in einem anderen Fenster neu laden müssen, können Sie einfach das Fenster schließen und es erneut aufrufen.

56
+0

Danke :) Ich habe versucht, die gleiche Quelle wieder zu binden, aber es aktualisiert die Daten nicht.Wenn ItemsSource = null gesetzt wurde und die richtige Quelle eine Aktualisierung durchgeführt hat, wurde SelectionChanged ausgelöst. Die Items.Refresh() funktionierte perfekt! – Gertjan

+0

Das funktioniert perfekt! –

+0

Funktioniert perfekt. Danke :) –

4

ich in gleiche Problem lief und fand, dass beste Platz für ObservableCollection Datacontext ist. Es gibt einige partielle Methoden, die vom Designer generiert wurden und die zum Aktualisieren der Sammlung verwendet werden können. Dieser Code funktioniert recht gut:

partial class DataClassesDataContext 
{ 
    private ObservableCollection<Task> taskCollection; 
    public ReadOnlyObservableCollection<Task> TaskView { get; private set; } 

    partial void OnCreated() 
    { 
     taskCollection = new ObservableCollection<Task>(Tasks); 
     TaskView = new ReadOnlyObservableCollection<Task>(taskCollection); 
    } 

    partial void InsertTask(Task instance) 
    { 
     taskCollection.Add(instance); 
     this.ExecuteDynamicInsert(instance); 
    } 

    partial void DeleteTask(Task instance) 
    { 
     taskCollection.Remove(instance); 
     this.ExecuteDynamicDelete(instance); 
    } 
} 
0

Aus irgendeinem Grund Items.Refresh() ist nicht für mich arbeiten. Was war Arbeit, um meine zugrunde liegende Sammlung erben ObservableCollection und rufen Sie dann seine Add Methode.

((ContactUIObjects)dgrdContacts.ItemsSource).Add(new ContactUIObject(o)); 

ContactUIObjects ist nur die Grids zugrunde liegenden Sammlung.

Verwandte Themen