none
WPF Datagrid aktualisiert nicht, wenn Source verändert mit LINQ to SQL RRS feed

  • Frage

  • Moin moin,

    ich verzweifle gerade an dem Problem der Aktualisierung eines DataGrids. Ich beschäftige mich erst ein paar Wochen mit C#, wollte aber gleich was aktuelles benutzen. Ich erzeuge in WPF ein Datagrid und binde die ItemsSource an einen LINQ to SQL DataContext. Das sieht in etwa so aus:

    <DataGrid Name="TestGrid" ItemsSource="{Binding}" AutoGenerateColumns="False" SelectionUnit="FullRow" IsReadOnly="True">
                        <DataGrid.Columns>
                            <DataGridTextColumn x:Name="Datum" Binding="{Binding Path=datum, StringFormat=dd.MM.yyyy}" Header="Datum" />

                            ...

                        </DataGrid.Columns>
    </DataGrid>

     

    Die Anbindung sieht dann so aus:

                testdbDataContext db = new testdbDataContext();

                TestGrid.ItemsSource = db.meinetabelle;

     

    Werden jetzt in diese "meinetabelle" außerhalb des DataGrids neue Werte eingetragen oder gelöscht, tauchen diese Änderungen erst auf, wenn ich das Fenster mit dem DataGrid einmal schließe und wieder öffne. Hat jemand vielleicht eine Idee, wie ich dort ansetzen kann? Ich verwende im übrigen .NET Framework 4.0 und entsprechend Visual Studio 2010. Die LINQ to SQL Klasse hat mir VS automatisch generiert, ich habe an ihr nichts geändert.

     

     

    Freitag, 19. November 2010 20:28

Antworten

  • Hallo CA.,

    Oft benutzt man da die Bindung an eine ObservableCollection, die nämlich durch Implementierung der INotifyCollectionChanged-Schnittstelle das CollectionChanged-Ereignis auslösen kann, wenn eine Änderung der zugrunde liegenden Auflistung vorliegt.

    [WPF DataGrid Practical Examples - CodeProject]
    http://www.codeproject.com/KB/WPF/WPFDataGridExamples.aspx

    _____________________

    Wenn man Listen hat, die kein CollectionChanged Ereignis werfen, kann man zum Beispiel auch etwas wie folgendes machen:

     private void btnDeinDataGrid_Click(object sender, RoutedEventArgs e)
     {
     deinDataGrid.ClearValue(DataGrid.ItemsSourceProperty);
     deinDataGrid.ItemsSource = db.DeineTabelle;
     }
    

    _________________

    Nebenbei ... für WPF-Fragen gibt es normal eine eigene WPF-Gruppe. Allerdings ist die Lösung (und Ursache) Deiner Frage fast Technologie-übergreifend ähnlich. Hier zum Beispiel eine Antwort in der Silverlight-Gruppe.


    ciao Frank

     

    • Als Antwort markiert ClarkeAI Samstag, 20. November 2010 11:14
    Samstag, 20. November 2010 08:05
  • Hallo CA.,

    das kann an mehreren Dingen liegen. Vielleicht mailst Du mir mal Dein Projekt (ggf. minimal reproduzierbar).
          -> PostAddFranksSeite.de
    Fragen wären u.a. wie AutoGenerateColumns gesetzt ist.
    Ein paar Beispiele auch:

      [Linq to Entities]    WpfNewItemSourceDemo.zip
      [Linq to SQL    WpfNewItemSourceDemo1.zip
      [Mit CollectionViewSource   WpfNewItemSourceDemo2.zip
     

    In einigen Fällen kann man auch:
          "deinDataGrid.Items.Refresh()" oder
          "CollectionViewSource.GetDefaultView(deinDataGrid.ItemsSource).Refresh();"
    benutzen - kommt darauf an. In meinem Beispiel-Download ist es sogar gar nicht notwendig.


    ciao Frank
    • Als Antwort markiert ClarkeAI Samstag, 20. November 2010 14:41
    • Bearbeitet Frank Dzaebel Sonntag, 21. November 2010 10:53
    Samstag, 20. November 2010 14:10

Alle Antworten

  • Hallo CA.,

    Oft benutzt man da die Bindung an eine ObservableCollection, die nämlich durch Implementierung der INotifyCollectionChanged-Schnittstelle das CollectionChanged-Ereignis auslösen kann, wenn eine Änderung der zugrunde liegenden Auflistung vorliegt.

    [WPF DataGrid Practical Examples - CodeProject]
    http://www.codeproject.com/KB/WPF/WPFDataGridExamples.aspx

    _____________________

    Wenn man Listen hat, die kein CollectionChanged Ereignis werfen, kann man zum Beispiel auch etwas wie folgendes machen:

     private void btnDeinDataGrid_Click(object sender, RoutedEventArgs e)
     {
     deinDataGrid.ClearValue(DataGrid.ItemsSourceProperty);
     deinDataGrid.ItemsSource = db.DeineTabelle;
     }
    

    _________________

    Nebenbei ... für WPF-Fragen gibt es normal eine eigene WPF-Gruppe. Allerdings ist die Lösung (und Ursache) Deiner Frage fast Technologie-übergreifend ähnlich. Hier zum Beispiel eine Antwort in der Silverlight-Gruppe.


    ciao Frank

     

    • Als Antwort markiert ClarkeAI Samstag, 20. November 2010 11:14
    Samstag, 20. November 2010 08:05
  • Vielen Dank für die Hinweise, bei der ObservableCollection bin ich leider noch nicht durchgestiegen, zumal das sicher einen großen Mehraufwand bedeutet, da ich ja nicht nur eine simple Tabelle binden will. Allerdings ist das wohl die Königslösung.

    Die ClearValue Methode kannte ich noch nicht. Ich habe sie auch gleich ausprobiert und man sieht quasi auch, dass die Tabelle neu aufgebaut wird, nur leider sind immer noch keine Änderungen zu sehen. Das passiert nach wie vor erst wieder, wenn das komplette Fenster geschlossen und wieder geöffnet wird, sehr schade. Vielleicht eine Idee, woran das liegen könnte?

    Und tut mir leid wegen der falschen Gruppe, hatte irgendwie gedacht, das passt eher zu C#, aber ist wohl doch eher ein WPF Thema, also nächstes Mal.

    Samstag, 20. November 2010 11:14
  • Hallo CA.,

    das kann an mehreren Dingen liegen. Vielleicht mailst Du mir mal Dein Projekt (ggf. minimal reproduzierbar).
          -> PostAddFranksSeite.de
    Fragen wären u.a. wie AutoGenerateColumns gesetzt ist.
    Ein paar Beispiele auch:

      [Linq to Entities]    WpfNewItemSourceDemo.zip
      [Linq to SQL    WpfNewItemSourceDemo1.zip
      [Mit CollectionViewSource   WpfNewItemSourceDemo2.zip
     

    In einigen Fällen kann man auch:
          "deinDataGrid.Items.Refresh()" oder
          "CollectionViewSource.GetDefaultView(deinDataGrid.ItemsSource).Refresh();"
    benutzen - kommt darauf an. In meinem Beispiel-Download ist es sogar gar nicht notwendig.


    ciao Frank
    • Als Antwort markiert ClarkeAI Samstag, 20. November 2010 14:41
    • Bearbeitet Frank Dzaebel Sonntag, 21. November 2010 10:53
    Samstag, 20. November 2010 14:10
  • Ja das Beispiel sieht schick aus, vielen Dank. Nur möchte ich nicht mit Datenquellen arbeiten, sondern die direkt die LINQ to SQL Klassen nutzen, aber da ist sicher auch kein großer Unterschied.

    Die anderen Refreshs hatte ich schon ausprobiert, die brachten gar nichts. Der Inhalt des DataGrids ändert sich, wenn ich der ItemsSource eine neue Quelle zuweise. Mache ich einen ClearValue und weise danach wieder dieselbe Quelle wie vorher zu, ändert sich gar nichts.

    Mittlerweile habe ich es allerdings geschafft, eine ObservableCollection zu schreiben, die dann auch hinzugefügte und entfernte Zeilen im DataGrid anzeigt. Nur darf ich wieder nichts bearbeiten, wenn die OC die Quelle ist, dann gibts einen Ausnahme-Fehler. Momentan fange ich das ab, indem ich wieder direkt an die db gehe. Beispielhaft:

    testdbDataContext db = new testdbDataContext();

    ObservableMeineTabelle _knownTabelle = new ObservableMeineTabelle(db);

    TestGrid.ItemsSource = _knownTabelle;

     

    beim Bearbeiten wechsele ich auf:

    TestGrid.ItemsSource = db.meinetabelle;

     

    Ist sicher keine sehr elegante Lösung, aber es funktioniert erst einmal. Wenn gar nichts mehr geht, komme ich gern auf das Angebot zurück und versuche das Projekt abgespeckt zu mailen.

    Ansonsten bin ich für alle Vorschläge offen.

     

    Gruß CA

    Samstag, 20. November 2010 14:50