Jap, du hast recht. Es wird mit this.Show(); eine neue Form mit geändertem Label angezeigt. Nur wie soll ich sonst das Event der Form1 zuweisen?
Also für Form2 gibt es eine Instanz beim Aufruf aus Form1 heraus.
private void menuItem2_Click(object sender, System.EventArgs e)
{
Form2 f2 = new Form2();
//f2.ShowDialog();
f2.Show();
}
Der Einstiegspunkt
static void Main()
{
Application.Run(new Form1(new FormObserver()));
}
und die Instanz von Form1 innerhalb Form2
private void button1_Click(object sender, System.EventArgs e)
{
//this.f1.TextLabel = this.textBox1.Text;
//this.Close();
FormObserver Fobs = new FormObserver();
Form1 f1 = new Form1(Fobs);
string temp = Fobs.TextBoxText(this.textBox1.Text);
f1.Detach();
this.Close();
}
Wobei ich mir nicht vorstellen kann, dass die Nachricht an die Falsche Instanz gesendet wird. Wenn ich in Form1 den Text Wert, z.B. auf Heinz stelle wird mir dies zwars im Debugger angezeigt, aber im Fenster selber nicht sichtbar gemacht.
Also warum das label null war habe ich jetzt wohl herausgefunden. Meiner Meinung nach wurde durch den Aufruf in Form2
private void button1_Click(object sender, System.EventArgs e)
{
//this.f1.TextLabel = this.textBox1.Text;
//this.Close();
Fobs = new FormObserver();
Form1 f1 = new Form1(Fobs);
Fobs.TextBoxText(this.textBox1.Text);
this.Close();
}
der überladene Konstruktor in Form1
public Form1(FormObserver fobs)
{
Fobs = fobs;
Fobs.TextChanged += new EventHandler(NewTextBoxText);
}
aufgerufen. Wenn ich nun
InitializeComponent();
mit in den überladenen Konstruktor packe dann ist mein label nicht mehr null.
Klingt irgendwie logisch. 8) Hätte mir schon viel früher auffallen müssen. 🤔
Zwars ist dadurch die NullReferenceException eleminiert aber es wird der Text des labels immer noch nicht geändert. Ich habe in das Event selber in Verdacht. Setze ich einen Breakpoint auf
private void NewTextBoxText(object sender, EventArgs e)
{
//Hierbei entsteht der Fehler zur Laufzeit
if(Fobs.ontext != null)
label1.Text = Fobs.ontext;
else
throw new NullReferenceException("Kein Wert übergeben");
}
label1.Text = Fobs.ontext;
so ist zu erkennen dass Fobs.ontext den korrekten Wert beinhaltet. Was ja allein schon durch die Ausnahmebehandlung sichergestellt ist.
Also mittlerweile bin ich mit meinem Halbwissen-Latein was Windowsprogrammierung mit C# und .NET betrifft am Ende. Hoffe ihr habt da noch ne Idee
Also ein Breakpoint auf NewTextBoxText zeigt, dass diese Funktion erst aufgerufen wird wenn ein Event gefeuert wurde, so wie es ja auch gedacht war. Allerdings sind bei Eintritt in die Funktion alle Form1() Steuerelemente null.
Ruft man die 2. Form auf sieht man über den Objektverweis das alle Steuerelemente der 1. Form null sind.
Im sender Objekt sind die targets auch null wenn das Event gefeuert wurde. Zusammengefasst sind die Steuerelemente null sobald das 2. Form aufgerufen wird und behalten diesen Wert auch wenn Form2() durch
this.Close();
beendent wird.
@herbivore
Ja da muss ich dir recht geben, habe wohl net aufmerksam genug den Text gelesen. Entschuldigung hierfür.
da mit
f = new Form1();
f.label1.Text = Fobs.ontext;
keine Exception mehr ausgelöst wird kann man doch davon ausgehen dass
this.label1.Text
die Exception auslöst. Nur frage ich mich wie label1 in diesem Fall NULL sein kann?
Mal ne allgemeine Frage zur Fehlermeldung oben:
Was bedeutet dieses genau?
Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
Also bei welchen Fehlern kann so eine Meldung kommen?
Ist nur ne Vermutung da ich mich mit ListView noch nicht beschäftigt habe, aber schon mal geschaut ob es möglich ist ein eigenes Event dafür zu schreiben?
In der MSDN Libary gibt es ein gutes Lernprogramm für Ereignisse.
Problem ist behoben. Nachdem die Datei mscoree.dll aus dem dotnetfx.cab ins Verzeichnis i386 kopiert wurde, liess sich das .NET Framework 1.1 sowie alle anderen Packages und Visual Studio .NET 2003 fehlerfrei installieren.
Ok das ist jetzt klar, wobei ich so etwas in der Art schon vermutet hatte. Gewundert hat mich nur, dass wenn man für Form1 f = new Form1(); auch alle in der Form enthalten Steuerelemente auswählen kann. Dadurch war ich etwas verwirrt.
Hierder genaue Fehlertext der zur Laufzeit erscheint wenn ich
private void NewTextBoxText(object sender, EventArgs e)
{
//f = new Form1();
//f.label1.Text = Fobs.ontext;
this.label1.Text = Fobs.ontext;
}
verwende.
Eine nicht behandelte Ausnahme des Typs 'System.NullReferenceException' ist in WindowsApplication1.exe aufgetreten.
Zusätzliche Informationen: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
Vielleicht hilft euch das ein wenig weiter.
Danke
Also ist Form1 f eine neue View oder ist es nur eine neue Instanz die auf diesselbe Form verweist?
Mein erster Gedanke war ja auch this zu nehmen. Leider kann ich die genaue Exception nicht wiedergeben, da sich .NET zur Zeit komplett auf meinem System hier auf der Diplomstelle verabschiedet hat. Sobald ich hier wieder arbeiten kann werde ich die Exception posten. Vielleicht bringt das etwas mehr Licht ins Dunkle. ?(
Danke.
Wenn ich ehrlich bin kannte ich die noch garnet, musste sie bisher auch nie verwenden. 8)
Bin jetzt alle in der Base angegebenen Fehlerbehebungsmethoden durchgegangen, ohne Erfolg. Nicht einmal die Fehlermeldung hat sich geändert. 🤔
Hi,
habe grosse Probleme VS .NET zu installieren. Beim ersten Versuch liessen sich die J# Pakete nicht installieren, da bin ich dann den Weg aus der Hilfe gegangen, und habe das Setup ohne Komponentencheck installiert. Das lief auch alles wunderbar durch bis kurz vorm Ende, da brach VS dann ab und führte seine Rollbackaktion durch ( ich glaub eine Komponente oder Assembly konnte nicht registriert werde). Da habe ich mir gedacht: Ok dann deinstallieren wir alles was mit dem Framework .NET zu tun hat und machen Windows für VS jungfräulich in dieser Hinsicht. Dies führte dazu, dass ich bis jetzt nicht einmal mehr das .NET Framework Package 1.1 installiert bekomme. Die Fehlermeldung vom .NET Framework hängt an.
Danke
@herbivore
Lieber spät als nie.
Ich bin über jede Hilfe dankbar und selbst wenn manches doppelt erklärt wird. Mit der Namensauswahl hast du sicherlich recht. Ich werde versuchen dies zu berücksichtigen.
Nachdem das mit dem Observer geklärt ist habe ich versucht den Observer auf meine Windowsapp anzuwenden.
Quellcodeausschnitt aus der Form1.cs
using Formobserver;
public class Form1 : System.Windows.Forms.Form
{
private FormObserver Fobs;
Form1 f;
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Erforderlich für die Windows Form-Designerunterstützung
//
InitializeComponent();
//
// TODO: Fügen Sie den Konstruktorcode nach dem Aufruf von InitializeComponent hinzu
//
}
public Form1(FormObserver fobs)
{
Fobs = fobs;
Fobs.TextChanged += new EventHandler(NewTextBoxText);
}
private void NewTextBoxText(object sender, EventArgs e)
{
f = new Form1();
MessageBox.Show("vorher: label: " + f.label1.Text);
f.label1.Text = Fobs.ontext;
MessageBox.Show("Erfolgreich" + f.label1.Text + Fobs.ontext);
//this.label1.Text = f.label1.Text;
}
}
Form2.cs
using FormObserver;
public class Form2 : System.Windows.Forms.Form
{
private FormObserver Fobs = null;
private void button1_Click(object sender, System.EventArgs e)
{
//this.f1.TextLabel = this.textBox1.Text;
//this.Close();
Fobs = new FormObserver();
Form1 f1 = new Form1(Fobs);
Fobs.TextBoxText(this.textBox1.Text);
this.Close();
}
}
FormObserver
using System;
namespace FormObserver
{
using System.Collections;
public class FormObserver
{
public EventHandler TextChanged;
public string ontext;
protected virtual void OnTextChanged(EventArgs e)
{
if(TextChanged != null)
TextChanged(this,e);
}
public string TextBoxText(string text)
{
ontext = text;
OnTextChanged(EventArgs.Empty);
//System.Windows.Forms.MessageBox.Show("ausgelöst: "+ontext);
return ontext;
}
}
}
Das Ereignis wird ausgelöst nur wird der Text des Labels nicht geändert. Wenn ich statt f.label1.text this.label1.Text schreibe bekomme ich eine Debuggermeldung wegen fehlendem Verweis auf eine Objektinstanz zur Laufzeit.
Aber eigentlich müsste es doch ein und dasselbe bedeuten oder?
Danke sehr!!!!!
Das hat mir den Sachverhalt gut verdeutlicht.
Gut das des mit dem Bug geklärt zu sein scheint, nur mein Prob ist immer noch net geklärt.... siehe meine Frage im Thread über guugsdu seinem
Danke erstmal,
musste feststellen, dass ich eine Zeile im C# Lernprogramm vergessen hatte:
private MyObserver Myobs; //geändert
public TestObserver(MyObserver myobs)
{
Myobs = myobs; //geändert aber versteh ich nicht
Myobs.Changed += new EventHandler(Addition); //geändert
}
erklären kann ich mir die Zeile nicht, warum ich einer Referenz einer Klasse das Objekt derselbigen Klasse zuweisen soll, aber so funktioniert es jetzt. Vielleicht kann es mir ja jemand erklären......
Ansonsten werde ich deinen Vorschlag auch einmal ausprobieren.
Danke
Nach deinem Code müsste die Windowsapp nach 10000 Zeichnungsdruchläufen wieder frei sein. Wenn sie danach immernoch blockiert ist, dürfte irgendwo in deinem Code eine Endlosschleife existieren.
Für weitere Hilfe zu Threads, hier der Link zum C# Lernprogramm für Threading
http://msdn.microsoft.com/library/DEU/csref/html/vcwlkThreadingTutorial.asp
Ansonsten kann ich dir sagen, dienen Threads der Synchronisation. Wenn du einen Teil eines Programmes in einem Thread auslagerst, z. Bsp. die ständige Abfrage eines Portes(Polling), so arbeitet dieser parallel zu dem Thread in dem Windowsapp arbeitet. In diesem Fall könntest du also weiterhin mit deiner Windowsapp interaggieren ohne dass dich das Polling eines Portes darin behindert. Es sei denn durchs Polling wird ein Interrupt(Ereignis) ausgelöst. 🙂
Habe mal ein bißchen gegoogelt und dabei folgenden Link gefunden:
http://www.akadia.com/services/dotnet_process_handling.html
Also als allererste Idee würde ich sagen, pack die Funktion für den Punkt in einen eigenen Thread, denn wenn ich das richtig sehe bleibt deine Windowsapp in der Funktion die den Punkt zeichnet hängen. Aus der würdest du ja dann nur herauskommen wenn der Punkt nicht mehr gezeichnet wird. Dies würde nicht bei einem eigenen Thread passieren.
Ich habe ein Problem bei dem Observer, wenn ich den Code ausführe wird mir zwars korrekterweise, durch die Konsolenausgabe angezeigt, dass ein Event ausgelöst wurde, jedoch bekomme ich einen Ausnahmefehler des Common Language Runtime Debbugging Services.
using System;
namespace Observer
{
using System.Collections;
public class MyObserver
{
public event EventHandler Changed;
protected virtual void OnChanged(EventArgs e)
{
if(Changed != null)
Changed(this, e);
}
public int Addition(int a, int b)
{
int c = a + b;
OnChanged(EventArgs.Empty);
return c;
}
}
}
using System;
namespace TestObserver
{
using Observer;
public class TestObserver
{
private MyObserver myobs;
public TestObserver(MyObserver myobs)
{
myobs.Changed += new EventHandler(Addition);
}
private void Addition(object sender, EventArgs e)
{
Console.WriteLine("Addition erfolgt");
}
public void Detach()
{
myobs.Changed -= new EventHandler(Addition);
myobs = null;
}
}
}
using System;
namespace Observer
{
using TestObserver;
public class TestEvents
{
public static void Main()
{
MyObserver obs = new MyObserver();
TestObserver tobs = new TestObserver(obs);
obs.Addition(3,4);
tobs.Detach();
}
}
}
Kommentiere ich die Zeile tobs.Detach() aus bekomme ich keine Fehlermeldung mehr. Da genau liegt mein Problem, denn wenn ich die EventHandler von .NET richtig verstehe muss doch der Delegat per -= aus dem Ereignis entfernt werden.
Alle 3 Klassen liegen in getrennten Dateien.
Hier noch der snapshot.......denke mal das am CrystalViewer liegt
Alles klar ich weiss jetzt woran es liegt. Nachdem mir ein snapshot der Konsolenmeldung gelungen ist, konnte ich erkennen das es am eingebundenen CrystalViewer liegt. Denn es werden hauptsächlich Fehlermeldungen mit dessen Engine in der Konsole angezeigt.
bisher für die Antworten. Eine letzte Bitte hätte ich @herbivore.Gibt es irgendwo ein Tutorial was die programmierung von einem Observer behandelt oder hast du Codebeispiele? Nehme natürlich auch Tipps von anderen entgegen. 🙂
Also die zweite Form wird nicht direkt von der ersten Form erzeugt sondern per Show() aufgerufen. Es sei denn das meintest du mit "erzeugen".
Habe mal nach MVC gegoogelt und auch einige Modellbeschreibungen dazu gefunden. Ist hierbei der von euch erwähnte Observer dasselbe wie die Views in den Modellen?
Die Frage ist jetzt ob dieses Konzept nicht zu aufwendig für mein Projekt ist. Denn in den einzelnen Forms sollen jediglich Daten eingegeben werden die dann im eigentlichen View angezeigt werden sollen. Beispiel: Über 2. Form wird eine Adresse eingegeben und in der 1. Form, wie bei einem Briefkopf eingetragen. Ich werde wohl auch die Eingabeforms als modale Dialoge gestalten. Dann sollen diese Daten noch in einer Datei gespeichert werden. Dafür sollte doch eigentlich Schnittstellen und Serialisierung ausreichen oder?
Ich finde diesen Thread sehr interessant, da ich seit einem Monat dabei bin mich in Windowsapplikationen mit .NET und C# einzuarbeiten. Da dies meine Diplomarbeit ist bin ich natürlich versucht, alles so sauber wie möglich zu programmieren.
Ich habe 2 Forms, jede hat ihre Klasse in getrennten Dateien. In der ersten Form existiert eine Eigenschaft über der es der 2. Form möglich ist den Text eines Labels in der 1. Form zu ändern.
Stellt dieses noch eine saubere Trennung der Forms dar? Oder handelt es sich hierbei schon um unsauberen Code?
Hallo,
ich habe da mal ne Verständnisfrage. Es existieren 2 Visual Studio .NET 2003 Projekte eines welches eine Windowsapplikation per Hand, also ohne den VS Codegenerator zu verwenden, erstellt beinhaltet und eine bei welcher der VS Codegenerator genutzt wurde. Diese Dateien habe ich nun auf einen anderen Rechner übertragen und wollte die .exe Dateien im Releaseordner dort starten. Ich bekomme jedoch immer einen Ausnahmefehler des Common Language Runtime Debugging Services, der mir nur sagt, dass ein Ausnahmefehler verursacht wurde der nicht verarbeitet werden konnte. Angezeigt bekomme ich nur die Prozess-ID und die Thread-ID.
Ich muss gestehen ich bin davon ausgegangen, dass ich wie beim VS C++ 6.0 die .exe Datei aus dem Release Ordner auf jedes andere Windowssystem übertragen kann.
Auf dem Quell- und Zielrechner ist jeweils WinXP Professional installiert. Auf dem Zielrechner ist das Framework .NET 1.1 installiert. Muss ich eine Installationsroutine basteln damit die Windowsapplikation auf dem Zielrechner gestartet werden kann?
Wie die Firma das dem Anwender klarmacht muss ja net meine Sorge sein. 🙂
Dennoch wüsste ich gerne wie ich die RS232 bediene mit C# ohne externe Programme.
Also bei MSDN findet man ja den Verweis auf NetSerialComm die eine Kommunikation mit Hilfe einer Klasse und DLL bereitstellt. Diese enthält die abstrakte Klasse CommBase welche von IDisposable erbt und eine Klasse CommBaseSettings in welcher sich folgender Eintrag in der Methode public bool Open() befindet:
Win32Com.DCB PortDCB = new Win32Com.DCB();
Ich kann hierbei nicht erkennen aus welcher Klasse Win32Com stammt noch welchen Verweis ich machen muss um Win32Com verwenden zu können.
Es scheint mir so, dass Win32Com ein Bestandteil der Win32 Api sein könnte doch finde ich im Quellcode keinen Hinweis auf die Implementierung dieser Api. Ich muss gestehen, dass ich im Moment sehr ratlos bin was diese Sache betrifft. Ich hoffe ihr könnt mich ein klein wenig erleuchten.
aber geht das net erst mit dem .NET 2005?????
also das mit der Setup-Routine wäre ja nur die absolute Spitze, so ne Art i-Tüpfelchen.
Dennoch wollte ich gleich so arbeiten dass es hinterher keine grossen Probleme bereitet.
Gibt es für .NET 2003 solche Libarys überhaupt oder muss ich mir was wrappen??? Habe da einiges über Win32Com gelesen.
Hi,
dies ist mein erster Thread in diesem Forum, also hoffe ich nicht gleich alles falsch zu machen.
Ich bin zur Zeit mit der Vorbereitung für meine Diplomarbeit beschäftigt. Für eine Firma soll ich eine Windowsapplikation schreiben welche in der Lage ist über serielle Schnittstelle Daten von einem Messgerät abzufragen. Da ich das genaue Datenformat dieser Daten noch nicht kenne und diese Software eigentlich in einem halben Jahr inklusive Setup-Routine verkaufsfertig sein soll wollte ich das Ansprechen der RS232 selber mit C# programmieren um hinterher den Aufwand für die Erstellung der Setup-Routine zu minimieren. Bisher habe ich bei meinen Recherchen nur fertige Sachen gefunden. Nirgendswo habe ich jedoch Informationen darüber gefunden von welcher Klasse man ableiten soll oder welches Assembly ich einsetzen muss. Ich bin auf dem Gebiet Visual Studio .NET und C# seit Anfang Februar in der Einarbeitung. Vorher habe ich mit der MFC gearbeitet. Ich hoffe hier auf schnelle Hilfe.
Schon mal Danke.