Hallo zusammen,
ich habe ein kleines Skript geschrieben welches eine CSV Datei einliest, bestimmte Operationen daran vornimmt und diese wieder abspeichert. Dies war ein Konsolenprogramm. Jetzt bin ich auf die Idee gekommen, es mal mit "Windows Forms" auszuprobieren. Was schon klappt ist z. B. das Auswählen des Pfads, das übergeben der Datei...
Allerdings war es bisher so, wenn es beim Einlesen zu einem Fehler gekommen ist, habe ich diesen direkt auf der Konsole ausgegeben (z. B. Zeile 3, Name fehlt).
Um die Fehlermeldungen ausgeben zu können, habe ich ein Richtextbox Namens "richTextBoxAusgabe" erstellt.
Es gibt ein Button, der das Einlesen startet. In der Datei "Form1.cs" habe ich u. A. folgenden Code stehen:
// Sobald man auf Öffnen klickt, bekommt man den OpenFileDialog geöffnet
private void btnEinlesen_Click(object sender, EventArgs e)
{
OpenFileDialog Ofd = new OpenFileDialog();
Ofd.Filter = "csv Dateien|*.csv|txt Dateien (*.txt)|*.txt|Alle Dateien (*.*)|*.*";
if (Ofd.ShowDialog() == DialogResult.OK)
{
// Übergebe den Pfad der Datei)
// Die Klasse CsvVerarbeiten liest die CSV Datei ein und prüft ob alles ausgefüllt ist in den jeweiligen Zeilen
CsvVerarbeiten csv = new CsvVerarbeiten (Ofd.FileName);
}
}
Und genau hier habe ich die Frage. In der Klasse CsvVerarbeiten hatte ich bisher immer Console.WriteLine... stehen, wenn es zu einem Fehler kommt.
Wie kann ich innerhalb dieser Klasse bzw. dem Objekt csv auf die RichTextBox mit dem Namen richTextBoxAusgabe zugreifen um mittels Append und System.Environoment.NewLine immer die jeweilige Meldung ausgeben zu können.
In der Klasse "public partial class Form1 : Form" kann ich ohne Probleme mittels richTextBoxAusgabe.Text += "xzy"; zugreifen, jedoch ist diese Klasse nicht in meiner CsvVerarbeiten verfügbar.
**Es ist auch absolut okay, wenn ihr mir Schlagworte gebt, wie ich das hinbekommen kann oder ein anderes Beispiel nennt, nach dem ich mal suchen soll.
Danke für eure Hilfe und einen schönen Abend!**
Hi,
für eine GUI Applikation empfiehlt es sich immer auf das drei Schichten Architektur zu setzen. [Artikel] Drei-Schichten-Architektur
Vor allem bei länger laufenden Operationen (=> Datei einlesen, verarbeiten, speichern), bietet sich Nebenläufigkeit, also async an:
[FAQ] Warum blockiert mein GUI?
Als Abendlektüre [FAQ] Kommunikation von 2 Forms bzw. mein eigener Artikel zum Thema: Kommunikation von 2 Forms.
Alternativ (zu Events) könntest du aber auch in deiner Klasse CsvVerarbeiten
eine eigene Exception
werfen und diese dann in deiner Form-Klasse fangen und dort in der RichtTextBox
den Fehler ausgeben.
für eine GUI Applikation empfiehlt es sich immer auf das drei Schichten Architektur zu setzen.
Vor allem bei länger laufenden Operationen (=> Datei einlesen, verarbeiten, speichern), bietet sich Nebenläufigkeit, also async an
Guten Abend Papst,
vielen Dank für deine Antwort. Genau das versuche ich zu realisieren (in Schichten). Ich könnte ja in die Logik/Prüfung einfach in die
private void btnEinlesen_Click(object sender, EventArgs e)
schreiben. Aber das kommt selbst mir als Anfänger relativ unsauber vor. Aber leider gibt es in diesem Beitrag keine Codebeispiele an denen "ich lernen könnte".
Das mit dem async ist eine gute Idee/guter Hinweis!
Als Abendlektüre
> bzw. mein eigener Artikel zum Thema:
> .Alternativ (zu Events) könntest du aber auch in deiner Klasse
CsvVerarbeiten
eine eigeneException
werfen und diese dann in deiner Form-Klasse fangen und dort in derRichtTextBox
den Fehler ausgeben.
Vielen Dank für deine Antwort! Hm ich weiß nicht ob es das trifft. Bei mir sind es ja keine zwei Forms sondern ein Objekt welches in die Form von der es aus aufgerufen wurde schreiben soll.
Leider komme ich mit den aktuellen Antworten mic nicht weiter. Ist da mein erster Beitrag vielleicht von mir zu schlecht erklärt, so dass man es falsch rüber kommt? Sollte ich es ggf nochmal besser erklären?
Das CSV einlesen wäre Deine Datenschicht.
Sofern es strukturelle Prüfungen sind, dann gehören diese ebenfalls in die Datenschicht - logische Prüfungen eben in die Logikschicht.
Schichten sind ein virtuelles Spektrum; man erkennt die Logik-Schicht nicht am Namen - es gibt dafür auch nicht "das eine Beispiel" - dafür sind Anwendungen viel zu verschieden.
Ich zB. für meinen Teil verwende in meinen Beispielen gern den CQS/CQRS Pattern für Logik.
https://github.com/BenjaminAbt/2018-Talks-ModernApiDevelopment/tree/master/src
Ich nenne sie in den Beispielen gerne Engine.
Dort gibt es eben Events (Queries, Commands) und Handlers (CommandHandler, QueryHandler).
Das ist eine sehr lose Art und Weise einer Logikschicht, die sehr viel ermöglich aber auch eine relativ hohe Lernhürde darstellt.
Anders ist zB. der Repository Pattern, der sowohl in der Daten- wie auch in der Logikschicht eine hohe Verbreitrungsrate hat.
public class IPersonRepository {}
public class PersonCsvRepository : IPersonRepository
{
public PersonCsvRepository(string csvFile)
{
// ...
}
}
public class IPersonService {}
public class PersonService : IPersonService
{
public PersonService(IPersonRepository personRepository)
{
// ...
}
}
Es kommt einfach auf die Anwendungen an und auch wie sinnvoll es ist, gewisse Dinge eher zu trennen oder eher pragmatisch vorzugehen.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Die beiden Artikel könnten auch "Kommunikation von unabhängigen Klassen" heißen, so daß sie also auch auf Form-Klasse oder sogar Klasse-Klasse zutreffen (eine Form ist ja auch nur eine Klasse).
Dort wird ja das Standardvorgehen erklärt: Verwendung von Ereignissen (Events), s.a. [FAQ] Eigenen Event definieren / Information zu Events (Ereignis/Ereignisse).
Daher habe ich auch "Alternativ (zu Events) ..." geschrieben.
Wenn du jedoch mehrere (bzw. alle Fehler) erst sammeln möchtest, dann lege doch einfach eine List<string>
-Eigenschaft in der Logik-Klasse an und nach Aufruf der Verarbeitungsmethode (welche dann diese Liste füllt), greifst du in der Form-Klasse darauf zu und zeigst sie in der RichTextBox
(oder ein beliebiges anderes Steuerelement) an.