Laden...

Code Strukturierung in mehere .cs Dateien

Erstellt von Franki vor 7 Jahren Letzter Beitrag vor 7 Jahren 1.307 Views
F
Franki Themenstarter:in
16 Beiträge seit 2016
vor 7 Jahren
Code Strukturierung in mehere .cs Dateien

Hallo,

ich habe nun ein paar Tage rum programmiert und meinen kompletten Code in die "Form1.cs" geschrieben.
Nun will ich, für bessere Übersicht, meinen Code auslagern.
Dazu habe ich bereits meine Buttons und Textboxen im Designer als Public deklariert.

Form1.cs



namespace Read_Write
{
    public partial class Form1 : Form

 private void btn_oeffnen_Click(object sender, EventArgs e)
        {
            ReadCSV(openFileDialog1.FileName, tempfrm);
        }
}

Read.cs


namespace Read_Write
{
    public class Read_CSV
    {
        private Form1 _frm;

        void ReadCSV(String file, Form1 tempForm)
        {
            _frm = tempForm;
            _frm.Clear_all();
          } 
     }
}

Wie rufe ich nun die ReadCSV in Form1 auf ?

lg

J
251 Beiträge seit 2012
vor 7 Jahren

[Artikel] Drei-Schichten-Architektur

vllt hilft dir det weiter

Buttons und Textboxen im Designer als Public deklariert.

Davon würde ich Abstand nehmen. Niemand außer die aktuelle Form sollte die Komponenten kennen.

[Edit] [FAQ] Kommunikation von 2 Forms sollte auch evtl nachgeschlagen werden, wenn ich mir deine Methode so genauer anschaue [/Edit]

2.298 Beiträge seit 2010
vor 7 Jahren

Wie Jamikus bereits sagte ist dein Ansatz eher schlecht.

Sauberer wäre hier das Lesen der CSV in eine eigene Klasse auszulagen und das Ergebnis an die Form zurück zu geben.

Je nach dem in welcher Form du die Daten ausgibst kannst du sie ja bereits geeignet zurück geben.

Als grobes Beispiel:


public class SettingsCSVReader
{
     private string _filePath;

     public CSVReader(string filePath)
     {
          _filePath = filePath;
     }

     public Settings ReadSettings()
     {
           // do read stuff
     }
}

public partial class Form1: Form
[
    private void btn_oeffnen_Click(object sender, EventArgs e)
    {
          OpenFileDialog opf = new OpenFileDialog();
          if(opf.ShowDialog() == DialogResult.OK)
          {
               SettingsCSVReader reader = new SettingsCSVReader(opf.FileName);
               this.Settings = reader.ReadSettings();
          }
    }
}

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

F
Franki Themenstarter:in
16 Beiträge seit 2016
vor 7 Jahren

ich habe das ganze nun etwas weiter angepasst.

Form1.cs


namespace Read_Write
{
    public partial class Form1 : Form

private void btn_oeffnen_Click(object sender, EventArgs e)
        {
            Form1 file = new Form1();     
            Read_CSV reader = new Read_CSV();
            reader.ReadCSV(openFileDialog1.FileName, file);
        }
}

ReadCSV.cs



namespace Read_Write
{
    public class Read_CSV
    {
        private Form1 _frm;

        public void ReadCSV(String file, Form1 tempForm)
        {
            _frm = tempForm;
            _frm.Clear_all();
            //read stuff....
         }
     }
}

Die unten stehende Fehlermeldung erscheint dann allerdings.> Fehlermeldung:

"Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt"

Was mache ich falsch ?

lg

2.207 Beiträge seit 2011
vor 7 Jahren

Hallo Franki,

dann ist irgendwass "null" was nicht null sein sollte, weil du auf das Objekt zugreifst.

[FAQ] NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt

Mit dem Debugger findest du heraus, was schief läuft.

[Artikel] Debugger: Wie verwende ich den von Visual Studio?

Sei dir halt bewusst, dass beispielsweise ein Form1 file = new Form1(); eine neue Instanz der Klasse "Form" macht. Da sollte es schon ein bisschen klingeln. 😃

Wieso heisst deine Form "file?

Gruss

Coffeebean

771 Beiträge seit 2009
vor 7 Jahren

Hi Franki,

mach es so wie inflames2k geschrieben hat. Die Form herumzureichen ist der falsche Ansatz.

F
Franki Themenstarter:in
16 Beiträge seit 2016
vor 7 Jahren

Sei dir halt bewusst, dass ein Form1 file = new Form1(); eine neue Instanz der Klasse "Form" macht.

Daran liegt es auch.
Habe mich nun an "inflames2k" post orientiert und nochmal etwas angepasst.

Form1.cs


namespace Read_Write
{
    public partial class Form1 : Form

public void Clear_all()
{
//
}

private void btn_oeffnen_Click(object sender, EventArgs e)
        {
            Read_CSV reader = new Read_CSV();
            reader.ReadCSV(openFileDialog1.FileName);
        }
}

READCSV.cs


namespace Read_Write
{
    public class Read_CSV
    {
        private Form1 _frm;

        public void ReadCSV(String file)
        {
            _frm.Clear_all();
            //read stuff....
         }
     }
}

Allerdings wird "_frm" nie etwas zugewiesen.

Wie rufe ich denn dann eine Methoder der Klasse "Form1.cs" auf

2.207 Beiträge seit 2011
vor 7 Jahren

Hallo Franki,

du kannst die derzeitige Form mit this übergeben. Aber dann ist die Komponente, die du aufruft ja extrem abhängig von der Form. Sie ist also anderswo kaum brauchbar. Und du hast sogar eine Forms-Dll-Abhängigkeit in einer Komponente, die "nur" ein Excel einlesen soll.

Wieso rufst du deine Clear-Methode nicht einfach auf, bevor du den Excel-Reader aufrufst? Dann kümmert sich die Form darum, dass sie alle ihre Sachen im UI bereinigt und die Excel-Komponente kümmert sich ums Lesen.

Andersrum formuliert: Wieso soll eine Excel-Lese-Komponente sich ums UI scheren? 😉

Allgemein: Wenn du aufteilen willst, dann überlege auch ein wenig, wer was machen soll bzw. wer für was zuständig ist ==> Separation of Concerns.

Gruss

Coffeebean

771 Beiträge seit 2009
vor 7 Jahren

Hi Franki,

Gar nicht 😜
Eine eigenständige Klasse sollte niemals eine Form-Methode aufrufen.
Wenn dann sollte die Form nur über [FAQ] Eigenen Event definieren / Information zu Events (Ereignis/Ereignisse) benachrichtigt werden und selber diese Methoden aufrufen.

Du kannst aber doch einfach vor dem Aufruf die Form-Elemente 'clearen':


private void btn_oeffnen_Click(object sender, EventArgs e)
{
    Clear_all();
    Read_CSV reader = new Read_CSV();
    reader.ReadCSV(openFileDialog1.FileName);
}

F
Franki Themenstarter:in
16 Beiträge seit 2016
vor 7 Jahren

ich verwende allerdings auch mehrfachen Zugriff auf Textboxen und ein datagridview.
Ich brauche unbednigt Zugriff auf meine Oberfläche. 🤔

2.207 Beiträge seit 2011
vor 7 Jahren

Hallo Franki,

Ich brauche unbednigt Zugriff auf meine Oberfläche.

Dann bist du noch nicht ganz am Ziel. Lies in der Komponente deine Excel ein. Gib die Daten zurück und was du dann damit anstellst am UI sollte die Excel-Lese-Komponente nicht interessieren.

Gruss

Coffeebean

16.834 Beiträge seit 2008
vor 7 Jahren

Brauchst Du in der Businesslogik Zugriff auf die UI, dann hast Du was falsch gemacht.
Das sollte immer vollständig entkoppelt sein. Immer.

F
Franki Themenstarter:in
16 Beiträge seit 2016
vor 7 Jahren

Danke auf jedenfall für eure Beiträge!
Die ganze Aktion zieht dann wohl einen riesen Rattenschwanz mit sich...

2.207 Beiträge seit 2011
vor 7 Jahren

Hallo Franki,

ja, wenn man damit startet, es nicht so kennt und es richtig machen will kann das rechten Impact haben. Du kannst aber ja mal das Lesen des Excels auslagern. Das sollte ja erstmal nichts tangieren. Dann kannst du die Klasse verwenden wo du es möchtest. Dann das UI in der einen Form umbauen insofern, als dass es die Daten von woanders her bekommt etc.

IMHO ist wichtig, dass du das nicht durchprügelst, weil du meinst es muss auf Gedeih und verderb so sein, sondern dass du dir Gedanken machst wie "Was kann ich wo auslagern", "Wieso muss dieunddie Komponente etwas über abc wissen, das geht sie gar nichts an", "Der hier soll nur für dasunddas zuständig sein" und so weiter. Sowas kommt mit der Zeit und Architekturen wachsen normalerweise. Das ist nicht mit einem mal so entstanden. Da findet auch ein ständiger Wechsel statt. Von daher: Keine Panik 😃

Irgendwann kannst du dann viel Code löschen - das ist einer der schönsten Teile 😉

Gruss

Coffeebean