Laden...

Wie mache ich ein Objekt in einem anderen Objekt bzw. Klasse am besten verfügbar?

Erstellt von mchrd vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.258 Views
M
mchrd Themenstarter:in
17 Beiträge seit 2018
vor 5 Jahren
Wie mache ich ein Objekt in einem anderen Objekt bzw. Klasse am besten verfügbar?

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!**

P
441 Beiträge seit 2014
vor 5 Jahren

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?

4.938 Beiträge seit 2008
vor 5 Jahren

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.

M
mchrd Themenstarter:in
17 Beiträge seit 2018
vor 5 Jahren

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 eigene Exception werfen und diese dann in deiner Form-Klasse fangen und dort in der RichtTextBox 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?

16.827 Beiträge seit 2008
vor 5 Jahren

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.

4.938 Beiträge seit 2008
vor 5 Jahren

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.