DataGridView und die Reihenfolge der Spalten

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von MasterQ.

    DataGridView und die Reihenfolge der Spalten

    Hallo,

    ich verwende ein einfaches WinForm zum Darstellen von Daten (DataGridView) aus einer BindingList<MeineKlasse>. Eine Spalte soll ausgeblendet werden und die Reihenfolge soll anders sein als in der Definition von MeineKlasse. Das Formular soll modal aufgerufen werden.

    Der Konstruktor sieht (inklusive extensivem Debugginggeschnösel) so aus!:

    C#-Quellcode

    1. public FrmTabelle(BindingList<KreditkarteEntity> source) {
    2. InitializeComponent();
    3. dataGridView.AutoGenerateColumns = true;
    4. dataGridView.DataSource = source;
    5. Debug.Print("Start");
    6. checkHeader();
    7. check();
    8. dataGridView.BindingContextChanged += _BindingContextChanged;
    9. dataGridView.ColumnDisplayIndexChanged += DisplayIndexChanged;
    10. dataGridView.ColumnRemoved += ColumnRemoved;
    11. dataGridView.ColumnAdded += ColumnAdded;
    12. Debug.Print("Events scharf");
    13. dataGridView.Columns["KEintragID"].Visible = false;
    14. //dataGridView.Columns["Konto"].Visible = false;
    15. //dataGridView.Columns["Belegdatum"].Visible = false;
    16. dataGridView.Columns["KEintragID"].DisplayIndex = 0;
    17. dataGridView.Columns["Buchungsdatum"].DisplayIndex = 1;
    18. dataGridView.Columns["Belegdatum"].DisplayIndex = 2;
    19. dataGridView.Columns["Buchungsbetrag"].DisplayIndex = 3;
    20. dataGridView.Columns["Erklärung"].DisplayIndex = 4;
    21. dataGridView.Columns["Beschreibung"].DisplayIndex = 5;
    22. dataGridView.Columns["BeschreibungZusatz"].DisplayIndex = 6;
    23. dataGridView.Columns["Konto"].DisplayIndex = 7;
    24. dataGridView.CellDoubleClick += DataGridView_CellDoubleClick;
    25. Debug.Print("händische Sortierung beendet");
    26. }


    und der Aufruf dann so:

    C#-Quellcode

    1. using (FrmTabelle Tabelle = new FrmTabelle(entities)) {
    2. if (Tabelle.ShowDialog() == DialogResult.OK) {
    3. using (KontoContext db = new KontoContext(new NpgsqlConnection(ConnectionString))) {
    4. db.KreditkarteEntities.AddRange(entities);
    5. db.SaveChanges();
    6. }
    7. }
    8. }



    Was läuft schief? Am Ende werden die Spalten nicht in der Reihenfolge angezeigt, die ich im Konstruktor vorgebe.

    Was ich beim Debuggen sehe ist, dass am Ende des Konstruktors die Werte von DisplayIndex genau so sind wie ich sie vorgebe. Sobald aber ShowDialog() aufgerufen wird, werden alle Spalten sukzessive entfernt (solange Spalten vorhanden sind, wird Spalte mit Index 0 gelöscht). Dann werden alle Spalten wieder eingefügt, allerdings nicht in der Reihenfolge (DisplayIndex) wie gewünscht. Der Abschluss macht dann das Event BindingContextChanged. Die Entitäten stammen nicht aus einer DB sondern werden aus einem File (csv) eingelesen, dann Zeilenweise in jeweils eine Entität übertragen und diese der BindingList hinzugefügt.

    Was veranlasst das Löschen der Spalten und warum passiert das? Was macht ShowDialog() da? Das macht doch keinen Sinn, oder?

    Gruß

    MQ

    PS: Unten die kleinen Helferlies und der Debugging Output (Vorsicht laaaang)

    Spoiler anzeigen


    C#-Quellcode

    1. void check() {
    2. List<string>listeIndex = new List<string>();
    3. List<string>listeDisplay = new List<string>();
    4. foreach (DataGridViewColumn item in dataGridView.Columns) {
    5. listeIndex.Add(item.Index.ToString("00"));
    6. listeDisplay.Add(item.DisplayIndex.ToString("00"));
    7. }
    8. string sIndex = string.Join(" ", listeIndex.ToArray());
    9. string sDisplay= string.Join(" ", listeDisplay.ToArray());
    10. string s = sIndex + "\n" + sDisplay;
    11. Debug.Print(s);
    12. }


    C#-Quellcode

    1. void checkHeader() {
    2. List<string>liste = new List<string>();
    3. foreach (DataGridViewColumn item in dataGridView.Columns) {
    4. liste.Add($"{item.HeaderText}({item.Index:00})");
    5. }
    6. Debug.Print(string.Join(" ", liste.ToArray()));
    7. }



    Der Output (stark gekürzt!!): Nachdem der Konstruktor beendet ist gehts folgendermaßen weiter:
    Spalte 00 löschen, DisplayIndizes neu ordnen, dann nächste Spalte, ...
    Dann Spalten wieder in der gleichen Reihenfolge (Index) einfügen und DisplayIndizes neu ordnet, nicht allerdings wie ursprünglich


    Quellcode

    1. Start
    2. KEintragID(00) Konto(01) Belegdatum(02) Buchungsdatum(03) Originalwährung(04) Kurs(05) Buchungswährung(06) Beschreibung(07) Erklärung(08) BeschreibungZusatz(09) Buchungsreferenz(10) Gebührenschlüssel(11) Länderkennzeichen(12) BAR_Referenz(13) AEE_Referenz(14) Abrechungskennzeichen(15) KategorieID(16) Buchungsbetrag(17) Originalbetrag(18)
    3. 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18
    4. 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18
    5. Events scharf
    6. Event DisplayIndexChanged ausgelöst von Buchungsdatum(03)
    7. KEintragID(00) Konto(01) Belegdatum(02) Buchungsdatum(03) Originalwährung(04) Kurs(05) Buchungswährung(06) Beschreibung(07) Erklärung(08) BeschreibungZusatz(09) Buchungsreferenz(10) Gebührenschlüssel(11) Länderkennzeichen(12) BAR_Referenz(13) AEE_Referenz(14) Abrechungskennzeichen(15) KategorieID(16) Buchungsbetrag(17) Originalbetrag(18)
    8. 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18
    9. 00 02 03 01 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18
    10. ...
    11. Event DisplayIndexChanged ausgelöst von Konto(01)
    12. Event DisplayIndexChanged ausgelöst von Belegdatum(02)
    13. Event DisplayIndexChanged ausgelöst von Belegdatum(02)
    14. Event DisplayIndexChanged ausgelöst von Konto(01)
    15. Event DisplayIndexChanged ausgelöst von Buchungsbetrag(17)
    16. 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18
    17. 00 04 02 01 05 06 07 08 09 10 11 12 13 14 15 16 17 03 18
    18. Event DisplayIndexChanged ausgelöst von Konto(01)
    19. Event DisplayIndexChanged ausgelöst von Originalwährung(04)
    20. Event DisplayIndexChanged ausgelöst von Kurs(05)
    21. Event DisplayIndexChanged ausgelöst von Buchungswährung(06)
    22. Event DisplayIndexChanged ausgelöst von Beschreibung(07)
    23. Event DisplayIndexChanged ausgelöst von Erklärung(08)
    24. Event DisplayIndexChanged ausgelöst von BeschreibungZusatz(09)
    25. Event DisplayIndexChanged ausgelöst von Buchungsreferenz(10)
    26. Event DisplayIndexChanged ausgelöst von Gebührenschlüssel(11)
    27. Event DisplayIndexChanged ausgelöst von Länderkennzeichen(12)
    28. Event DisplayIndexChanged ausgelöst von BAR_Referenz(13)
    29. Event DisplayIndexChanged ausgelöst von AEE_Referenz(14)
    30. Event DisplayIndexChanged ausgelöst von Abrechungskennzeichen(15)
    31. Event DisplayIndexChanged ausgelöst von KategorieID(16)
    32. 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18
    33. 00 04 02 01 05 06 07 08 09 10 11 12 13 14 15 16 17 03 18
    34. ...
    35. 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18
    36. 00 07 02 01 08 09 10 05 04 06 11 12 13 14 15 16 17 03 18
    37. händische Sortierung beendet
    38. ...
    39. 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17
    40. 06 01 00 07 08 09 04 03 05 10 11 12 13 14 15 16 02 17
    41. KEintragID gelöscht, Index 00, Displayindex 00
    42. Konto gelöscht, Index 00, Displayindex 06
    43. Belegdatum gelöscht, Index 00, Displayindex 01
    44. Buchungsdatum gelöscht, Index 00, Displayindex 00
    45. Originalwährung gelöscht, Index 00, Displayindex 04
    46. Kurs gelöscht, Index 00, Displayindex 04
    47. Buchungswährung gelöscht, Index 00, Displayindex 04
    48. Beschreibung gelöscht, Index 00, Displayindex 02
    49. Erklärung gelöscht, Index 00, Displayindex 01
    50. BeschreibungZusatz gelöscht, Index 00, Displayindex 01
    51. Buchungsreferenz gelöscht, Index 00, Displayindex 01
    52. Gebührenschlüssel gelöscht, Index 00, Displayindex 01
    53. Länderkennzeichen gelöscht, Index 00, Displayindex 01
    54. BAR_Referenz gelöscht, Index 00, Displayindex 01
    55. AEE_Referenz gelöscht, Index 00, Displayindex 01
    56. Abrechungskennzeichen gelöscht, Index 00, Displayindex 01
    57. KategorieID gelöscht, Index 00, Displayindex 01
    58. Buchungsbetrag gelöscht, Index 00, Displayindex 00
    59. Originalbetrag gelöscht, Index 00, Displayindex 00
    60. KEintragID hinzugefügt, Index 00, Displayindex 00
    61. Konto hinzugefügt, Index 01, Displayindex 01
    62. Belegdatum hinzugefügt, Index 02, Displayindex 02
    63. Buchungsdatum hinzugefügt, Index 03, Displayindex 01
    64. Originalwährung hinzugefügt, Index 04, Displayindex 04
    65. Kurs hinzugefügt, Index 05, Displayindex 05
    66. Beschreibung hinzugefügt, Index 07, Displayindex 05
    67. Erklärung hinzugefügt, Index 08, Displayindex 04
    68. BeschreibungZusatz hinzugefügt, Index 09, Displayindex 06
    69. Buchungsreferenz hinzugefügt, Index 10, Displayindex 10
    70. Gebührenschlüssel hinzugefügt, Index 11, Displayindex 11
    71. Länderkennzeichen hinzugefügt, Index 12, Displayindex 12
    72. BAR_Referenz hinzugefügt, Index 13, Displayindex 13
    73. AEE_Referenz hinzugefügt, Index 14, Displayindex 14
    74. Abrechungskennzeichen hinzugefügt, Index 15, Displayindex 15
    75. KategorieID hinzugefügt, Index 16, Displayindex 16
    76. Buchungsbetrag hinzugefügt, Index 17, Displayindex 03
    77. Originalbetrag hinzugefügt, Index 18, Displayindex 18
    78. BindingContextChanged ausgelöst


    Muss die Reihenfolge der Spalten immer anders sein? Wenn nicht, dann lege sie doch gleich im Designer in der Ordnung an, wie du sie brauchst und lass das mit dem DisplayIndex. Und was passiert, wenn du das hier auskommentierst?

    MasterQ schrieb:

    dataGridView.AutoGenerateColumns = true;
    Die Reihenfolgen bzw. die Spaltenbelegung ist nicht fest, da das Formular für verschiedene Entitätsklassen aufgerufen wird. Die Spalten mit dem Designer festzulegen macht daher keinen Sinn.

    Ich kann die Spalten natürlich auch dynamisch je nach Entitätsklasse hinzufügen. Das werde ich dann auch tun wenn ich nicht dahinter steige, wie ich das Problem mit den automatisch erzeugten Spalten lösen kann.

    Im Moment interessiert mich aber, warum das mit den DislayIndizes nicht funktioniert, denn genau so kann man das auf den Seiten von MS nachlesen und so sollte es funktionieren. Tut's aber nicht und ich weiß nicht warum.

    Setze ich AutoGenerateColumns auf false, dann werden auch keine Spalten beim Setzen der Datenquelle angefügt. Das wäre dann die Option wenn ich die Spalten direkt mit Code erzeuge.

    Gruß

    MQ

    --EDIT--
    PS.: Es ist wohl so, dass der Konstruktor schlicht der falsche Ort für das Setzen der Spaltenreihenfolge ist. In der Eventroutine Shown() angesiedelt, kommt das raus, was ich erwarte.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „MasterQ“ ()