Laden...

DataGrid und ObservableCollection Problem :-/

Erstellt von Luna1987 vor 13 Jahren Letzter Beitrag vor 13 Jahren 5.039 Views
L
Luna1987 Themenstarter:in
43 Beiträge seit 2009
vor 13 Jahren
DataGrid und ObservableCollection Problem :-/

Hy @ all.

Wiedermal DataGrid-Probleme 😦

Erstmal worum es geht:
Ich habe ein TreeView, in dem ich verschiedene TreeViewItems anklicken kann.
-Root
---Child1
------DataGrid0
---Child2
------DataGrid1
------DataGrid2
---Child3
...

Wenn ich auf DataGrid0, DataGrid1 etc. klicke, soll ein gefülltes DataGrid angezeigt werden. Wenn mir dieses DataGrid angezeigt wird erscheinen in meiner GUI zusätzlich zwei Buttons "Zeile hinzufügen" und "Zeile entfernen". Wenn ich nun Zeile entfernen klicke, soll die letzte Zeile des gerade angezeigten DataGrids entfernt werden.
Das soll also passieren.

Nun die "Vorgehensweise":
Ich habe eine Klasse Stationen, in der eine ObservableCollection gefüllt wird:
(Code wurde von mit gekürtzt/vereinfacht)


class Stationen
{
        public static ObservableCollection<Stationen> _StationsCollection;

        public string Name { get; set; }
        public int ID { get; set; }

        public static ObservableCollection<Stationen> fill(string nameOfItem)
        {
            _StationsCollection = new ObservableCollection<Stationen>();

            for (int n = 0; n < 10; n++)
            {
                _StationsCollection.Add(new Stationen()
                {
                    Name = nameofItem + n,
                    ID = n
                });
            }

            return _StationsCollection;
        }

        public ObservableCollection<Stationen> StationsCollection
        {
            get
            {
                return _StationsCollection;
            }
        }
    }

Für ein DataGrid sollen Spalten erzeugt und die ObservableCollection dann an das DataGrid gebunden werden:


// Code für Spalten erzeugen....

// ObservableCollection binden
dataGrid.ItemsSource = Stationen.fill("Test");

Dann wird mir auch das DataGrid angezeigt - bis hier alles wunderbar.

Jetzt will ich die ObservableCollection aber nicht nur an EIN DataGrid binden, sondern an x-beliebige (jedes DataGrid hat einen anderen Namen, nutzt aber die gleiche ObservableCollection):


DataGrid datagrid1 = new DataGrid();
datagrid1.name = "dataGrid1";
...
datagrid1.ItemsSource = Stationen.fill("Test1");
...

DataGrid datagrid2 = new DataGrid();
datagrid2.name = "dataGrid2";
...
datagrid2.ItemsSource = Stationen.fill("Test2");
...

Das geht soweit auch, d.h. wenn ich in meinem TreeView auf das Item "DataGrid 1" klicke, dann wird mir DataGrid1 mit gefüllten Inhalt angezeigt, gleiches bei "DataGrid 2" usw.

ABER: wenn ich nun mir DataGrid1, DataGrid2 und DataGrid3 (in der Reihenfolge) angeguckt habe und wieder zu DataGrid1 gehe und dann auf den Button "Zeile entfernen" klicke, dann entfernt er nicht bei DataGrid1 eine Zeile, sondern bei DataGrid3!!! Er entfernt also von der "letzten erzeugten" ObservableCollection die Zeile.

Hier noch der Code für (letzte) "Zeile entfernen":


Stationen._StationsCollection.RemoveAt(datagrid.Items.Count - 1);

Was mache ich nun? Ich hoffe ihr versteht mein Problem und könnt mir helfen. (Achja und ich möchte NICHT unbedingt eine ListView, oder DataGridView etc. verwenden! sondern es schon "auf diesem Weg schaffen")
DANKE 🙂

PS: Anbei noch ein Screenshot auf dem der TreeView, die Buttons und ein gefülltes DataGrid zu sehen sind.

4.931 Beiträge seit 2008
vor 13 Jahren

Hallo,

ist doch klar, daß du den Fehler bekommst 😉
Du greifst ja mittels 'StationsCollection' auf die statische Variable '_StationsCollection' zu (und diese wird ja immer vom letzten Aufruf der Fill-Methode gesetzt).

Entferne ersteinmal diese statische Member-Variable (und dann auch noch 'public' - pfui)!
Und greife im OOP-Sinne korrekt auf die ItemsSource-Eigenschaft des aktuellen DataGrids zu (natürlich beim Zugriff auf die ObservableCollection<> entsprechend 'casten')-

Aber ein großes Lob für deine ausführliche Beschreibung 👍

L
Luna1987 Themenstarter:in
43 Beiträge seit 2009
vor 13 Jahren

Hallo Th69.

Danke für deine schnelle Antwort. Ich bin noch nicht so ganz fit auf dem Gebiet, darum noch einige Fragen 😦

Okay, habe die statische Member-Variable entfernt...
--> In der fill-Methode wird auch kein Fehler angezeigt
--> aber Visual Studio sagt mir hier:


public ObservableCollection<Stationen> StationsCollection
{
      get
      {
            return _StationsCollection;
       }
}

dass _StationsCollection "nicht im aktuellen Kontext vorhanden ist!?
Wenn ich dann daraus einfach


public ObservableCollection<Stationen> StationsCollection { get; set; }

mache, kann ich nicht mehr auf die Collection zugreifen. Also kann ich nicht mehr folgende Abfrage machen:


Stationen._StationsCollection.RemoveAt(datagrid.Items.Count - 1); 

Das ist schonmal das "erste Problem".

Dann weiß ich leider auch ich nicht was du mit

... Und greife im OOP-Sinne korrekt auf die ItemsSource-Eigenschaft des aktuellen DataGrids zu (natürlich beim Zugriff auf die ObservableCollection<> entsprechend 'casten') meinst 8o

Ich hoffe du kannst noch mal helfen 🙁

458 Beiträge seit 2007
vor 13 Jahren
public ObservableCollection<Stationen> StationsCollection  
{  
      get  
      {  
            return _StationsCollection;  
       }  
}  

dass _StationsCollection "nicht im aktuellen Kontext vorhanden ist!?

Richtig, das Feld gibt es ja auch nichtmehr.

Wenn ich dann daraus einfach

public ObservableCollection<Stationen> StationsCollection { get; set; }  

mache, kann ich nicht mehr auf die Collection zugreifen. Also kann ich nicht mehr folgende Abfrage machen:

Stationen._StationsCollection.RemoveAt(datagrid.Items.Count - 1);  

Du hast nun ein Auto-Property StationsCollection, dann kannst du natuerlich nichtmehr auf dein ehemaliges Feld _StationsCollection zugreifen, das ist ja weg.
Wenn dann muesstest du auf dein Property StationsCollection.

Dann weiß ich leider auch ich nicht was du mit

... Und greife im OOP-Sinne korrekt auf die ItemsSource-Eigenschaft des aktuellen DataGrids zu (natürlich beim Zugriff auf die ObservableCollection<> entsprechend 'casten')

meinst geschockt

Er meint, dass dein DataGrid ein ItemsSource Property hat, das die Datenquelle enthaelt.
Du kannst dir die Liste als folgendermaßen holen:


var myObservableCollection = myDataGrid.ItemsSource as ObservableCollection<Stationen>();

aequitas

be the hammer, not the nail!

4.931 Beiträge seit 2008
vor 13 Jahren

Hallo Luna1987,

die Grundlagen von C# (bzw. der OOP) solltest du aber beherrschen, bevor du mit WPF arbeitest. Ich selber arbeite mich auch gerade in WPF ein, aber ohne die Grundlagen würde ich manchmal auch wie ein "Ochs' vor'm Berge stehen" 😉

Auch dein Klassendesign würde ich etwas abändern:
anstatt der statischen Methode 'Fill' erzeuge lieber eine Klasse, welche von ObservableCollection<Stationen> ableitet und greife darüber dann von deinem DataGrid aus zu:


class StationenListe : ObservableCollection<Stationen>
{
  StationenListe(string nameOfItem)
  {
    // ...
  }
}

// in deiner Window-Klasse
datagrid.ItemsSource = new StationenListe("test");

Das Auslesen hat dir ja 'aequitas' schon gepostet.

L
Luna1987 Themenstarter:in
43 Beiträge seit 2009
vor 13 Jahren

Hallo aequitas und Th69.

Danke für eure Hilfe 🙂
Es funktionier nun wunderbar 😉

Eine Frage habe ich aber noch (ohne gleich einen neuen ForumBeitrag zu starten):
Nun möchte ich gerne auch beliebig viele Spalten zu meinem DataGrid auf Knofdruck hinzufügen können.

Mittels


// Spalte zum DataGrid hinzufügen
DataGridTextColumn newTextColumn = new DataGridTextColumn();
newTextColumn.Header = "NeueSpalte";
newTextColumn.Binding = new Binding("NeueSpalte");
datagrid.Columns.Add(newTextColumn);

füge ich zwar eine neue Spalte ein, aber sobald ich eine Zelle aus der "neuen" Spalte bearbeiten möchte, stoppt das Programm und sagt (logischerweise), dass keine Bindung dafür vorhanden ist. Denn in meiner Klasse habe ich ja diese Spalte nicht definiert.
Wie mache löse ich das nun? Muss ich für die Columns auch noch irgendwie eine ObservableCollection anlegen? Oder ganz andere Ansätze?

Wäre nett Tipps von euch zu bekommen 😉

P
660 Beiträge seit 2008
vor 13 Jahren

Das DataGrid hat eine Property "AutoGenerateColumns" die du auf True setzen kannst.

MfG
ProGamer*Der Sinn Des Lebens Ist Es, Den Sinn Des Lebens Zu Finden! *"Wenn Unrecht zu Recht wird dann wird Widerstand zur Pflicht." *"Ignorance simplifies ANY problem." *"Stoppt die Piraterie der Musikindustrie"