Entwickler-Ecke
IO, XML und Registry - Nur bestimmte Elemente aus XML-Datei in DataGridView anzeige
JM80 - Sa 07.04.12 23:43
Titel: Nur bestimmte Elemente aus XML-Datei in DataGridView anzeige
Hallo,
ich habe die folgende xml-Datei in ein Dateset eingelesen und möchte sie in zwei DataGridViews anzeigen.
Im ersten DataGridView möchte ich Gruppen anzeigen und im zweiten die ChannelNos.
Das klappt soweit auch ganz gut, allerdings werden im zweiten Grid alle ChannelNo angezeigt.
Ich möchte aber dass nur die ChannelsNos angezeigt werden, dessen Gruppe im ersten Grid selektiert wird.
Wie lässt sich das am besten umsetzen?
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
| <?xml version="1.0"?> <Servicelist> <Favoritelist> <FavoriteGroup> <Name>Gruppe1</Name> <ServiceType>TV</ServiceType> <ChannelNo>1</ChannelNo> <ChannelNo>2</ChannelNo> <ChannelNo>3</ChannelNo> </FavoriteGroup> <FavoriteGroup> <Name>Gruppe2</Name> <ServiceType>TV</ServiceType> <ChannelNo>4</ChannelNo> <ChannelNo>5</ChannelNo> <ChannelNo>6</ChannelNo> </FavoriteGroup> <FavoriteGroup> <Name>Gruppe3</Name> <ServiceType>TV</ServiceType> </FavoriteGroup> <FavoriteGroup> <Name>Gruppe4</Name> <ServiceType>Radio</ServiceType> <ChannelNo>101</ChannelNo> <ChannelNo>102</ChannelNo> <ChannelNo>103</ChannelNo> </FavoriteGroup> <FavoriteGroup> <Name>Gruppe5</Name> <ServiceType>Radio</ServiceType> <ChannelNo>104</ChannelNo> <ChannelNo>105</ChannelNo> <ChannelNo>106</ChannelNo> </FavoriteGroup> <FavoriteGroup> <Name>Gruppe6</Name> <ServiceType>Radio</ServiceType> </FavoriteGroup> </Favoritelist> </Servicelist> |
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| private void button1_Click(object sender, EventArgs e) { string filePath = "D:\\favlist.xml"; MyDataSet.ReadXml(filePath);
dataGridView1.DataSource = MyDataSet; dataGridView1.DataMember = "FavoriteGroup"; dataGridView2.DataSource = MyDataSet; dataGridView2.DataMember = "ChannelNo"; } |
So sieht es zur Zeit aus. (bmp, 727.4 KB)
Th69 - So 08.04.12 10:58
Hallo Jana :welcome:
um nur die zur Gruppe zugehörigen ChannelNos anzuzeigen benötigst du eine Filterung.
Diese wird durch die BindingSource-Klasse bereitgestellt:
C#-Quelltext
1: 2: 3: 4:
| BindingSource bs = new BindingSource(); bs.DataSource = MyDataSet; dataGridView2.DataSource = bs; dataGridView2.DataMember = "ChannelNo"; |
Die BindingSource wird also dazwischen geschaltet.
Um nun die Filterung durchzuführen, solltest du im CurrentCellChanged (oder aber SelectionChanged)-Ereignis des ersten DataGridViews (Gruppe) folgenden (bzw. ähnlichen) Code einfügen:
C#-Quelltext
1: 2: 3:
| int rowIndex = dataGridView1.CurrentCell.RowIndex; string sValue = dataGridView1.Rows[rowIndex].Cells[0].Value.ToString(); bs.Filter = "Name = '" + sValue + "'"; |
Dazu mußt du dann die BindingSource-Variable
bs als Klassenmember anlegen!
Genaueres zur Syntax der Filterung findest du unter
DataColumn.Expression-Eigenschaft [
http://msdn.microsoft.com/de-de/library/system.data.datacolumn.expression.aspx].
Ich hoffe, dies funktioniert so einwandfrei mit einem DataSet (da ich bisher immer nur direkt mit DataTables gearbeitet habe).
P.S. Für deine 2. Frage habe ich ein eigenes Thema angelegt:
DataSet: neue Zeile wird an falscher Stelle gespeichert [
http://www.c-sharp-forum.de/viewtopic.php?t=109013]
JM80 - So 08.04.12 12:16
Danke für den Tip mit dem Filter, aber leider funktioniert es so auch nicht.
Ich habe direkt einen Filter für Gruppe1 gesetzt, aber es werden noch immer die Channels aller Gruppen angezeigt.
Mein Code sieht zu zeit folgenermaßen aus:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| private void button1_Click(object sender, EventArgs e) { string filePath = "D:\\favlist.xml"; MyDataSet.ReadXml(filePath);
dataGridView1.DataSource = MyDataSet; dataGridView1.DataMember = "FavoriteGroup"; BindingSource bs = new BindingSource(); bs.DataSource = MyDataSet;
bs.Filter = "Name = 'Gruppe1'";
dataGridView2.DataSource = bs; dataGridView2.DataMember = "ChannelNo"; } |
JM80 - So 08.04.12 12:54
Ich hab mir das Dataset mal in der Schnellansicht angesehen:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
| Tabelle: Favoritelist
Favoritelist_Id --------------- 0
Tabelle: FavoriteGroup
Name ServiceType FavoriteGroup_Id Favoritelist_Id ---------------------------------------------------------------- Gruppe1 TV 0 0 Gruppe2 TV 1 0 Gruppe3 TV 2 0 Gruppe4 Radio 3 0 Gruppe5 Radio 4 0 Gruppe6 Radio 5 0
Tabelle: ChannelNo_Text
ChannelNo_Text FavoriteGroup_Id -------------------------------- 1 0 2 0 3 0 4 1 5 1 6 1 101 3 102 3 103 3 104 4 105 4 106 4 |
Sieht so aus, als ob ich irgendwie über die FavoriteGroup_Id filtern muss.
Th69 - So 08.04.12 20:46
Hallo,
probiere also mal:
C#-Quelltext
1:
| bs.Filter = "FavoriteGroup_Id = 0"; |
Wenn das klappt solltest du die FavoriteGroup_Id aus der ersten DataGridView so erhalten:
C#-Quelltext
1: 2: 3:
| int rowIndex = dataGridView1.CurrentCell.RowIndex; int nValue = (int)dataGridView1.Rows[rowIndex].Cells["FavoriteGroup_Id"].Value; bs.Filter = "FavoriteGroup_Id = " + nValue; |
Wenn nicht, dann kriegst du eine Exception, daß die Spalte nicht existiert...
JM80 - So 08.04.12 21:30
Hallo,
das funktioniert leider auch nicht, es werden weiterhin alle ChannelNos angezeigt. Es scheint als ob der Filter wirkungslos ist.
Der folgende Filter nach ChannelNo funktioniert übrigends auch nicht.
C#-Quelltext
1:
| bs.Filter = "ChannelNo_Text ='101'" |
Th69 - Mo 09.04.12 11:09
Hallo JM80,
sorry, das es so nicht funktioniert - ich habe mal im Internet gesucht und unter
BindingSource.Filter - Zeigt keine Wirkung [
http://www.mycsharp.de/wbb2/thread.php?postid=211396] hatte jemand dieselben Probleme damit (leider wohl auch keine direkte Lösung).
Versuchen wir mal jetzt einen anderen Ansatz (den von mir erwähnten mittels einer DataTable). Mittels einer DataView läßt sich ähnliches (Filterung und Sortieren) wie mit einer BindingSource erledigen - einzig, daß direkt eine DataTable anstatt einem DataSet benötigt wird.
C#-Quelltext
1: 2: 3: 4:
| DataTable dataTable = MyDataSet.Tables["ChannelNo_Text"]; DataView dataView = new DataView(dataTable); dataView.RowFilter = "ChannelNo_Text ='101'"; dataGridView.DataSource = dataView; |
Viel Erfolg!
P.S. Einen Einstieg in DataTable/DataView gibt es unter
Filtern und aggregieren mit ADO.NET [
http://msdn.microsoft.com/de-de/library/bb979485.aspx]
JM80 - Mo 09.04.12 15:02
Hallo Th69,
mit einer kleinen Änderung funktioniert die Filterung nun.
C#-Quelltext
1: 2: 3: 4: 5:
| DataTable dataTable = MyDataSet.Tables["ChannelNo"]; dataViewChannels = new DataView(dataTable); dataViewChannels.RowFilter = "FavoriteGroup_ID = 1"; dataGridView2.DataSource = dataViewChannels; |
Das Ändern des Filter bei SelectionChanged funktioniert auch. Aber ich musste es auch etwas abändern.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| private void dataGridView1_SelectionChanged(object sender, EventArgs e) { if (dataViewChannels != null) { int rowIndex = dataGridView1.CurrentCell.RowIndex; int nValue = (int)MyDataSet.Tables["FavoriteGroup"].Rows[rowIndex].ItemArray.ElementAt(2); dataViewChannels.RowFilter = "FavoriteGroup_ID = " + nValue; } } |
Allerdings kann ich jetzt im dataGridView2 keine neue ChannelNo mehr eingeben, bzw. wird sie nach der Eingabe direkt wieder gelöscht.
JM80 - Mo 09.04.12 22:34
So, hab grad nochmal ein paar Dinge getestet.
Die neu eingegebenen ChannelNos werden im Dataset gespeichert. Sie werden nur nicht angezeigt, da sie direkt ausgefiltert werden.
Wenn ich den Filter entferne kann ich neue Werte eingeben und sie bleiben sichtbar. Wenn ich den Filter auf "ChannelNo_Text ='101'" setze kann ich weitere Channels mit der No 101 eingeben welche auch sichtbar bleiben.
Also müsste nach der Filterung mit
dataViewChannels.RowFilter = "FavoriteGroup_ID = " + nValue;
für alle neu eingegebenen ChannelNos die FavoriteGroup_ID automatich auf die aktuell gefilterte Gruppe gesetzt werden. Mal schauen ob ich das noch irgendwie hinbekomme.
Th69 - Di 10.04.12 12:16
Hallo JM80,
schön, daß es jetzt bei dir funktioniert.
Das DataGridView.DefaultValuesNeeded-Ereignis müßtest du abonnieren und dort kannst du dann die Spaltenwerte vorinitialisieren.
JM80 - Mi 11.04.12 07:23
Hallo Th69,
das manuelle vorinitialisieren bekomme ich so leider nicht hin. Aber was funktioniert ist das Setzen eines Defaultwertes für die Column direkt nach dem Ändern des Filters.
C#-Quelltext
1:
| dataViewChannels.Table.Columns[1].DefaultValue = nValue; |
Also kann ich nun neue Werte eingeben, welche auch richtig gespeichert und amgezeigt werden.
Leider habe ich noch keine Möglichkeit gefunden wie ich die Werte für die FavoriteGroup_ID manuell ändern kann. Aber genau das werde ich noch benötigen, da es mein Ziel ist eine ChannelNo von einer FavoriteGroup in eine andere zu verschieben. Wenn ich dafür die Spalte FavoriteGroup_ID irgendwie einblenden könnte um diese manuell einzuztragen würde mir das fürs erste genügen.
Schön wäre es jedoch wenn ich sie per drag and drop verschieben könnte aber das ist wahrscheinlich viel zu kompliziert für mich.
JM80 - Sa 14.04.12 00:35
Woran kann es liegen, das sich mit
C#-Quelltext
1:
| dataViewChannels.Table.Rows[0].ItemArray[0] = "100"; |
kein Wert zuweisen läßt?
Vor der Zuweisung steht dort "1" drin, nach der Zuweisung steht dort immernoch "1".
Wenn ich beim debuggen den Wert überwache und ihn mit 'Wert bearbeiten' ändere, dann wird er auch direkt wieder auf "1" zurückgesetzt. Allerdings ändert sich die Farbe des Wertes von schwarz in rot.
Th69 - Sa 14.04.12 10:14
Hallo JM80,
benutze statt
ItemArray den Indexer (denn mit dem ItemArray erhältst du (wohl) eine Kopie der Werte):
C#-Quelltext
1:
| dataViewChannels.Table.Rows[0][0] = "100"; |
JM80 - Sa 14.04.12 22:00
Vielen Dank,
so wird doch alles gleich viel einfacher.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!