Laden...

Problem mit JSON und korrekter Listview anzeige

Erstellt von Friedmann vor einem Jahr Letzter Beitrag vor einem Jahr 701 Views
Friedmann Themenstarter:in
3 Beiträge seit 2023
vor einem Jahr
Problem mit JSON und korrekter Listview anzeige

Hallo liebe Gemeinde,
ich bin neu bei euch und lerne mich auch gerade selber neu in C# ein, deswegen habe ich mir erstmal ein kleines Projekt vorgenommen. Das ist ein Ein und Ausgaben Dokumentationen Programm. Dazu habe ich dieses Script für das eintragen und ansehen der Einnahmen geschrieben im Zusammenhang mit einem WPF Formular. Doch anscheinend mache ich irgendwas falsch.

Die JSON Datei wird richtig angelegt und der Eintrag auch richtig gemacht:


{"Art":"Gehalt (monatlich)","Summe":23.50,"Datum":"2023-02-21T00:00:00+01:00","Einheit":"Konto"}

Leider wird aber im ListView nur die Art angezeigt und nicht das Subitem Summe dazu. Kann mir einer erklären wo ich den Fehler gemacht habe und mir vielleicht auch erklären, worauf man am besten dann achtet, wenn man mit JSON schreiben, lesen und ändern arbeitet?


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
using Formatting = Newtonsoft.Json.Formatting;

namespace FinanzCheck
{
    public partial class EinAdd : Form
    {
        private string finanzCheckOrdner = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "FinanzCheck");
        private string einnahmeOrdner = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "FinanzCheck", "Einnahme");

        public EinAdd()
        {
            InitializeComponent();

            // Überprüfe, ob die Ordner FinanzCheck und Einnahme vorhanden sind. Wenn nicht, lege sie an.
            if (!Directory.Exists(finanzCheckOrdner))
            {
                Directory.CreateDirectory(finanzCheckOrdner);
            }

            if (!Directory.Exists(einnahmeOrdner))
            {
                Directory.CreateDirectory(einnahmeOrdner);
            }
        }

        private void EinAdd_Load(object sender, EventArgs e)
        {
        
        }

        private void btnEinHin_Click(object sender, EventArgs e)
        {
            // Erstelle ein Eintrag-Objekt aus den Formular-Eingabefeldern
            Eintrag eintrag = new Eintrag();
            eintrag.Art = comboEinArt.SelectedItem.ToString();
            eintrag.Summe = decimal.Parse(AddEinSum.Text);
            eintrag.Datum = dateTimePicker1.Value.Date;
            eintrag.Einheit = comboEinEi.SelectedItem.ToString();

            // Erstelle den Dateinamen
            string dateiname = $"Einnahme-{eintrag.Art}-{eintrag.Summe}-{eintrag.Datum.ToString("yyyyMMdd")}.json";

            // Speichere Eintrag als JSON-Datei
            string json = JsonConvert.SerializeObject(eintrag);
            string dateipfad = Path.Combine(einnahmeOrdner, dateiname);
            File.WriteAllText(dateipfad, json);

            // Bestätigungsnachricht anzeigen
            MessageBox.Show("Eintrag wurde erfolgreich hinzugefügt!");
        }

        private void btnListAus_Click(object sender, EventArgs e)
        {
            // Suche alle JSON-Dateien im Einnahme-Ordner
            string[] jsonDateien = Directory.GetFiles(einnahmeOrdner, "Einnahme-*.json");

            // Lese Daten aus JSON-Dateien und füge sie zur Liste hinzu
            List<Eintrag> eintraege = new List<Eintrag>();
            foreach (string jsonDatei in jsonDateien)
            {
                string jsonString = File.ReadAllText(jsonDatei);
                Eintrag eintrag = JsonConvert.DeserializeObject<Eintrag>(jsonString);
                eintraege.Add(eintrag);
            }

            // Sortiere Einträge nach Datum absteigend
            eintraege = eintraege.OrderByDescending(e => e.Datum).ToList();

            // Zeige Einträge in der Liste an
            listView1.Items.Clear();
            foreach (Eintrag eintrag in eintraege)
            {
                string[] eintragArray = {
                    eintrag.Art,
                    eintrag.Summe.ToString("C"),
                    eintrag.Datum.ToString("yyyy-MM-dd"),
                    eintrag.Einheit
                };
                ListViewItem listViewItem = new ListViewItem(eintragArray);
                listViewItem.SubItems.Add(eintrag.Summe.ToString("C"));
                listView1.Items.Add(listViewItem);
            }
        }

        private class Eintrag
        {
            public string Art { get; set; }
            public decimal Summe { get; set; }
            public DateTime Datum { get; set; }
            public string Einheit { get; set; }
        }
    }
}


Liebe Grüße

4.942 Beiträge seit 2008
vor einem Jahr

Hallo und willkommen,

setze die ListView-Eigenschaft View auf Details.

PS: Dein Thema ist im falschen Unterforum, "GUI: Windows-Forms" wäre besser - vllt. verschiebt es aber ein Moderator?

Friedmann Themenstarter:in
3 Beiträge seit 2023
vor einem Jahr

Hallo Th69.

Danke für deine Information. Ich werde das mal versuchen und mir genauer durchlesen ^^

Es tut mir leid, das ich den Beitrag falsch platziert habe. Es wäre toll, wenn ein Moderator diesen verschieben wurde.

Friedmann Themenstarter:in
3 Beiträge seit 2023
vor einem Jahr

Also als kleiner Zwischenstand, ich habe mir die Doku noch einmal durchgelesen und mein Script ein wenig ausgebessert:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using Formatting = Newtonsoft.Json.Formatting;

namespace FinanzCheck
{
    public partial class EinAdd : Form
    {
        private string finanzCheckOrdner = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "FinanzCheck");
        private string einnahmeOrdner = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "FinanzCheck", "Einnahme");

        public EinAdd()
        {
            InitializeComponent();

            // Überprüfe, ob die Ordner FinanzCheck und Einnahme vorhanden sind. Wenn nicht, lege sie an.
            if (!Directory.Exists(finanzCheckOrdner))
            {
                Directory.CreateDirectory(finanzCheckOrdner);
            }

            if (!Directory.Exists(einnahmeOrdner))
            {
                Directory.CreateDirectory(einnahmeOrdner);
            }
        }

        private void EinAdd_Load(object sender, EventArgs e)
        {

            // Setze die Eigenschaften der ListView
            listView1.View = View.Details;
            listView1.FullRowSelect = true;
            listView1.Columns.Add("Art", 100);
            listView1.Columns.Add("Summe", 100);
            listView1.Columns.Add("Datum", 100);
            listView1.Columns.Add("Einheit", 100);

        }

        private void btnEinHin_Click(object sender, EventArgs e)
        {
            // Suche alle JSON-Dateien im Einnahme-Ordner
            string[] jsonDateien = Directory.GetFiles(einnahmeOrdner, "Einnahme-*.json");

            // Lese Daten aus JSON-Dateien und füge sie zur Liste hinzu
            List<Eintrag> eintraege = new List<Eintrag>();
            foreach (string jsonDatei in jsonDateien)
            {
                string jsonString = File.ReadAllText(jsonDatei);
                Eintrag eintrag = JsonConvert.DeserializeObject<Eintrag>(jsonString);
                eintraege.Add(eintrag);
            }

            // Sortiere Einträge nach Datum absteigend
            eintraege = eintraege.OrderByDescending(e => e.Datum).ToList();

            // Konfiguriere ListView für Details-Ansicht
            listView1.View = View.Details;
            listView1.FullRowSelect = true;
            listView1.GridLines = true;

            // Füge Spalten hinzu
            listView1.Columns.Add("Einnahmeart", 100, HorizontalAlignment.Left);

            // Zeige Einträge in der Liste an
            listView1.Items.Clear();
            foreach (Eintrag eintrag in eintraege)
            {
                string[] eintragArray = {
                    eintrag.Art
                };
                ListViewItem listViewItem = new ListViewItem(eintragArray);
                listViewItem.SubItems.Add(eintrag.Summe.ToString("C"));
                listViewItem.SubItems.Add(eintrag.Datum.ToString("yyyy-MM-dd"));
                listViewItem.SubItems.Add(eintrag.Einheit);
                listView1.Items.Add(listViewItem);
            }
        }

        private class Eintrag
        {
            public string Art { get; set; }
            public decimal Summe { get; set; }
            public DateTime Datum { get; set; }
            public string Einheit { get; set; }
        }
    }
}

Jetzt habe ich schon einmal erreicht das die 4 Spalten nun als Kategorien angezeigt werden. Gerade muss ich noch rausfinden, warum die jeweiligen Einträge nun nicht angezeigt werden. Denke da werde ich die Doku dazu noch mal ein wenig genauer lesen müssen. Ich hatte es zwar hinbekommen, durch:


// Suche alle JSON-Dateien im Einnahme-Ordner
string[] jsonDateien = Directory.GetFiles(einnahmeOrdner, "Einnahme-*.json");

// Lese Daten aus JSON-Dateien und füge sie zur Liste hinzu
List<Eintrag> eintraege = new List<Eintrag>();
foreach (string jsonDatei in jsonDateien)
{
    string jsonString = File.ReadAllText(jsonDatei);
    Eintrag eintrag = JsonConvert.DeserializeObject<Eintrag>(jsonString);
    eintraege.Add(eintrag);
}

// Sortiere Einträge nach Datum absteigend
eintraege = eintraege.OrderByDescending(e => e.Datum).ToList();

// Konfiguriere ListView für Details-Ansicht
listView1.View = View.Details;
listView1.FullRowSelect = true;
listView1.GridLines = true;

// Füge Spalten hinzu
listView1.Columns.Add("Einnahmeart", 100, HorizontalAlignment.Left);
listView1.Columns.Add("Summe", 100, HorizontalAlignment.Right);
listView1.Columns.Add("Datum", 100, HorizontalAlignment.Left);
listView1.Columns.Add("Einheit", 100, HorizontalAlignment.Left);

// Zeige Einträge in der Liste an
listView1.Items.Clear();
foreach (Eintrag eintrag in eintraege)
{
    string[] eintragArray = {
        eintrag.Art,
        eintrag.Summe.ToString("C"),
        eintrag.Datum.ToString("yyyy-MM-dd"),
        eintrag.Einheit
    };
    ListViewItem listViewItem = new ListViewItem(eintragArray);
    listView1.Items.Add(listViewItem);

da hat er dann aber warum auch immer die Spalten doppelt angelegt. Ich hoffe ich werde auch dazu die Lösung finden in der Doku ^^ Ansonsten werde ich mich hier noch einmal im Thread melden 🙂

4.942 Beiträge seit 2008
vor einem Jahr

Du hast die Spalten doch schon in der Methode EinAdd_Load erzeugt und fügst dann noch mal in btnEinHin_Click neue hinzu (wenn es sich um statische Spalten handelt ist es m.E. am einfachsten, diese schon im VS-Designer anzulegen).

Bezgl.

Gerade muss ich noch rausfinden, warum die jeweiligen Einträge nun nicht angezeigt werden

Bist du schon mit dem Debugger vertraut: [Artikel] Debugger: Wie verwende ich den von Visual Studio?

Desweiteren solltest du das Einlesen der JSON-Daten in eine eigene Klasse auslagern (Stichwort: Trennung von UI, Logik und DAL), s. [Artikel] Drei-Schichten-Architektur.

Leider unterstützt die WinForms-ListView kein DataBinding, sonst wäre das die eleganteste Art der Datenanzeige (als Alternative käme dazu ein DataGridView in Betracht, s.a. Vergleich DatagridView - ListView).