2009-05-30 32 views
21

Mam DataFrid WPF z niektórych danych. Możesz dodawać wiersze w oddzielnym oknie. DataContext jest taki sam, obiekt LINQ-SQL. Powiązanie jest również takie samo, wiążę właściwość "ItemsSource" z tabelą.Jak odświeżyć ramkę danych WPF?

W drugim oknie, gdy użytkownik kliknie "Zapisz", utworzę wiersz programowo i doda go za pomocą "InsertOnSubmit". Następnie używam metody "SubmitChanges" DataContext.

Mój problem polega na tym, że DataGrid nie jest aktualizowana. Jeśli ponownie uruchomię aplikację, zobaczę nowy wiersz, więc znajduje się on w bazie danych, ale nie mogłem znaleźć sposobu na odświeżenie DataGrid.

Do tej pory próbowałem użyć "UpdateTarget" w BindingExpression DataGrid, ale to nie pomogło. Próbowałem również "dataGrid.Items.Refresh()" - ten sam wynik. Jak mogę to naprawić?

Odpowiedz

20

Powodem, dla którego nie jest aktualizowanie, jest to, że LINQ-SQL nie implementuje INotifyCollectionChanged, więc WPF nie ma możliwości poinformowania, że ​​ItemsSource zostało zaktualizowane. Najmniej przerażającym sposobem, aby to naprawić, jest skopiowanie wyników LINQ-SQL do ObservableCollection - kiedy robisz Insert, dodaj także do obserwowalnej kolekcji. Następnie zobaczysz aktualizację.

+0

Twoje rozwiązanie oczywiście działa. Po prostu pomyślałem, że mogę uciec prostym znacznikom powiązania XAML. – KovBal

+0

Jeśli używamy ObservableCollection jako pomostu między linq do sql a formantem, to w jaki sposób możemy użyć SubmitChanges(), aby odesłać wynik z powrotem do bazy danych? – MemoryLeak

+3

@MemoryLeak - więc tutaj jest trochę trudniej; nie tylko chcesz wiedzieć, kiedy zmieni się * kolekcja * (tj. co oznacza INotifyCollectionChanged), chcesz także wiedzieć, kiedy zmieni się którykolwiek z elementów *. Musisz więc zasubskrybować zmianę kolekcji, a następnie dodać/usunąć, subskrybować INOTifyPropertyChanged każdego elementu. * Wtedy * musisz zdecydować, co zapisać na podstawie powiadomień, które otrzymujesz. –

2

Problem polega na tym, że należy odświeżyć dane LINQ do SQL DataContext. DataContext nie rozpozna poprawnie nowego wiersza nawet po przesłaniu zmian. Musisz zutylizować DataContext i utworzyć nowy. W większości przypadków DataContext powinien być używany do jednej krótkiej operacji, a nie jako obiektu długiego.

+0

Twoje rozwiązanie jest bardzo podobne do Pwninsteina. Niestety wynik jest taki sam, ponieważ zdarzenie DataContextChanged nie powoduje odświeżenia DataGrid. – KovBal

0

Lub po prostu wywołaj kod wyszukiwania ponownie (zwykle przycisk wyszukiwania)> Rozwiązałem go w moim przypadku w ten sposób.

1

Jeśli masz przypadek, gdy musisz przeładować siatkę w innym oknie, możesz po prostu zamknąć to okno i wywołać je ponownie.

56
+0

Dziękuję :) Próbowałem ponownie powiązać to samo źródło, ale nie zaktualizowałem danych.Ustawienie ItemsSource = null, a następnie poprawne źródło spowodowało aktualizację, ale spowodowało wyrzucenie SelectionChanged. Items.Refresh() działał idealnie! – Gertjan

+0

To działa idealnie! –

+0

Działa idealnie. dzięki :) –

4

wpadłem na ten sam problem i okazało się, że najlepszym miejscem do ObservableCollection jest DataContext. Ma pewne częściowe metody generowane przez projektanta, które można wykorzystać do aktualizacji kolekcji. Ten kod działa całkiem dobrze:

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

Z jakiegoś powodu Items.Refresh() nie pracuje dla mnie. Co sprawiło, że moja podstawowa kolekcja odziedziczyła ObservableCollection, a następnie zadzwonił na jej metodę Add.

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

ContactUIObjects to tylko podstawowe kolekcje siatki.

Powiązane problemy