Entwickler-Ecke

WinForms - Wie kann ich eine ListView mit mehreren Pfaden verknüpfen?


Csharp-programmierer - Fr 29.05.15 14:49
Titel: Wie kann ich eine ListView mit mehreren Pfaden verknüpfen?
Hallo Leute. Ich habe eine ListView. Das Programm dient einem Restaurant. In der ListView stehen nun alle Speisen / Getränke.
Um eine neue Speise zu speichern habe ich folgenden Code:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
using(StreamWriter writer = new StreamWriter(path))
{
writer.Write(name);
writer.Write(preis);
writer.Write(zutaten);
writer.Close();
}


es wird also in eine TextDatei gespeichert. Wenn ich nun eine Speise auswähle, brauche ich den Pfad dieser Datei, um die Datei zu öffnen. Meine ListView hat 2 Spalten : Speise und Pfad

Nun möchte ich, dass in der ListView alle Namen der Speisen stehen und bei dem Pfad jeweils der dazugehörige Pfad, WIe kann ich dass machen?

LG :)


Th69 - Fr 29.05.15 17:46

Was genau willst du wissen? Wie du wieder an die Pfade der Textdateien kommst? Wer bestimmt denn die Pfade und den Namen der Textdateien (der Anwender oder das Programm)?

Wie du siehst, gibt deine Anfrage viele Gegenfragen (da zumindestens mir nicht genau klar ist, was dein eigentliches Problem ist?).

M.E. wäre es besser, es gäbe nur einen vorgegebenen Pfad (z.B. im AppData-Verzeichnis), wo die Dateien (wenn es denn Dateien und keine DB sein soll) dann entsprechend des Speisenamens abgelegt werden.


Csharp-programmierer - Sa 30.05.15 20:59

Im Endeffekt soll bei dem ersten Programmstart folgendes passieren:
- Ein Ordner soll dort angelegt werden, wo das Programm läuft.
- 2 Unterorder Namens Speisen, Getränke
- Wenn man eine neue Speise speichern will, soll eine .txt Datei in den jeweiligen Ordner.

In der ListVew für Getränke, sollen nun alle Getränke drinne stehen. In der anderen Spalte soll dann der Pfad der Datei stehen. Also: Pommes C:\User\.....

Und das halt für jeden File in dem Ordner.

PS: das Programm soll ich dann einem Kumpel geben. Geht das so einfach mit der Installation auf dem PC meines Kumpels?

MFG Cinnay :)


C# - Sa 30.05.15 22:38

Warum soll den der Pfad zur Textdatei in der ListView stehen? Für wen ist die View? Wenn sie nämlich für den User ist macht es in meinen Augen wenig Sinn den Pfad zur Datei anzuzeigen. Was soll er denn damit Anfangen. Außerdem sind nach deiner Beschreibung die Pfade nach einem Muster aufgebaut (Ich denke mal die txt Datei benennst du nach dem Namen der Speise): "<Programmpfad>\Speisen\<Name>.txt"

Aber zu deinem eigentlichen Problem:
1. Hole dir alle Pfade zu den Textdateien in deinem Speise-Verzeichnis:

C#-Quelltext
1:
string[] speisen = Directory.GetFiles("Speisen\", "*.txt");                    

2. Füge sie deiner ListView hinzu:

C#-Quelltext
1:
2:
3:
4:
5:
6:
foreach (string speise in speisen)
{
    string name = Path.GetFileNameWithoutExtension(speise);
    ListViewItem item = new ListViewItem(new [] {name, speise});
    deineListView.Add(item);
}


Das ganze geht natürlich analog mit den Getränken.

Wenn du die Anwendung auf einen anderen PC übertragen willst, reicht es, wenn du die .exe im \Debug\ bzw. \Release\ Ordner deines Projektes kopierst (und alle eingbundenen Ressourcen wie z.B. DLLs oder Settingsfiles, ...). Auf dem Zielrechner muss dann das Framework installiert sein, dass du in deinem Projekt verwendest (z.B. Net-Framework v4.0)


Csharp-programmierer - So 31.05.15 10:23

Vielen Lieben Dank. Nun werden alle Files aus dem Ordner "Speisen" in der ListView angezeigt. Nun brauche ich aber für jede TextDatei die Pfade, da wenn ein Gast eine Speise auswält, per StreamReader die Information der Speise in eine andere ListView übertragen wird. Und für den StreamReader brauche ich den Pfad.


C#-Quelltext
1:
2:
3:
4:
using(StreamReader reader = new StreamReader(PfadDerMirFehlt))
{
 
}


Aber sonst vielen Dank für Ihre hilfreiche Antwort.
MFG :)


Ralf Jansen - So 31.05.15 11:29

Die Hürde ist jetzt mittlerweile so niedrig das es zu einfach ist einfach die Lösung zu sagen.
Du hast die Daten jetzt in einem ListView jetzt musst du die des selektierten Items wieder aus der Listview rausbekommen.

Also Klick einfach mal F1 auf deinem ListView und schau dir in der Dokumentation die verfügbaren Properties an. Die haben sprechende Namen und deren Dokumentation beinhaltet wiederum fast immer Codebeispiele. Die passende Property zu finden sollte dich also nur ein paar Sekunden kosten.


jfheins - So 31.05.15 11:35

Hat das eigentlich einen bestimmten Grund, dass du nicht einfach alles in einer Datei speicherst?
Dann hättest du eine Liste im Hintergrund in der alles drin ist und kannst dem Benutzer davon das anzeigen was ihn interessiert.

Wenn du bei der aktuellen Lösung immer wieder auf die Festplatte zugreift, hast du mehr Fehlerquellen (jeder Dateizugriff kann auch in "Zugriff verweigert enden") und wenn die HDD Energie spart und erst wieder anläuft kann das auch 1-2 sek. dauern.


Wenn du alles in einer XML speicherst könnte das Laden z.B. so aussehen:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
var xmls = new XmlSerializer(typeof(List<Speisekarteneintrag>));
using (var file = new StreamReader(@"Speisekarte.xml"))
{
  Karte = (List<Speisekarteneintrag>) xmls.Deserialize(file);
}

// Alle Einträge
foreach (var eintrag in Karte)
{
  listView1.Items.Add(new ListViewItem(new[] {eintrag.Name, eintrag.Preis.ToString()}));
}
// Nur was scharfes
foreach (var eintrag in Karte.Where(x => x.Schärfegrad > 0))
{
  listView1.Items.Add(new ListViewItem(new[] { eintrag.Name, eintrag.Preis.ToString() }));
}

Und schon hast du alle Information im Speicher und kannst du die Liste nach belieben und schnell zugreifen.

Klasse wäre dann so:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
  public class Speisekarteneintrag
  {
    public Art Art { get; set; }

    public string Name { get; set; }

    public int Preis { get; set; }

    public int Schärfegrad { get; set; }
  }

  public enum Art
  {
    Speise,
    Getränk
  }


Ich weiß jetzt nur nicht, wie gut du dich auskennst. Wenn dir das zu hoch ist, bitte ignorieren :angel:


Csharp-programmierer - So 31.05.15 12:15

Vielen Dank für Ihre antwort. Und wie speichere ich jetzt eine XML - Datei in dem Ordner?

Und geht die Festplatte davon kaputt, wenn man das mit der Methode von davor (mit StreamReader) macht?
MFG :D


jfheins - So 31.05.15 12:54

Speichern ginge z.B. so:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
Karte.Add(new Speisekarteneintrag
{
  Art = Art.Getränk,
  Name = "Tomatensaft",
  Preis = 319,
  Schärfegrad = 1
});

var xmls = new XmlSerializer(typeof(List<Speisekarteneintrag>));
using (var file = new StreamWriter(@"Speisekarte.xml"))
{
  xmls.Serialize(file, Karte);
}


Wobei man die XML natürlich auch händisch bearbeiten/erstellen kann.

Die HDD geht dadurch nicht kaputt, aber es kann halt sein, dass es länger dauert. HDD Zugriffzeit ist 10ms bis 1500ms, RAM ist üblicherweise bei einigen Nanosekunden. Also um ein vielfaches schneller.


Csharp-programmierer - So 31.05.15 19:11

Mal eine Frage: welches Objekt verstehen Sie als Karte?
MFG Cinnay :)


C# - So 31.05.15 21:56


C#-Quelltext
1:
List<Speisekarteneintrag> Karte = new List<Speisekarteneintrag>();                    


Er benutzt einfach eine Liste. Den Typ übergibt er auch dem XmlSerializer.

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
Karte.Add(new Speisekarteneintrag
{
  Art = Art.Getränk,
  Name = "Tomatensaft",
  Preis = 319,
  Schärfegrad = 1
});

var xmls = new XmlSerializer(typeof(List<Speisekarteneintrag>));
using (var file = new StreamWriter(@"Speisekarte.xml"))
{
  xmls.Serialize(file, Karte);
}


Th69 - Mo 01.06.15 08:22

Tipp: Eine kurze Einführung zum XmlSerializer gibt es unter Mit XmlSerializer Objekte als XML speichern und laden [http://www.entwickler-ecke.de/topic_Mit+XmlSerializer+Objekte+als+XML+speichern+und+laden_64947.html]


Csharp-programmierer - Do 04.06.15 19:32

Vielen Dank für meine Mithelfen. Ihr seit echt nett. Klappt nun. LG :)