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
[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]
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 |
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
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
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Hi Franki,
mach es so wie inflames2k geschrieben hat. Die Form herumzureichen ist der falsche Ansatz.
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
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
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
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);
}
ich verwende allerdings auch mehrfachen Zugriff auf Textboxen und ein datagridview.
Ich brauche unbednigt Zugriff auf meine Oberfläche. 🤔
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
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Brauchst Du in der Businesslogik Zugriff auf die UI, dann hast Du was falsch gemacht.
Das sollte immer vollständig entkoppelt sein. Immer.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Danke auf jedenfall für eure Beiträge!
Die ganze Aktion zieht dann wohl einen riesen Rattenschwanz mit sich...
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
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck