Entwickler-Ecke
WinForms - form wird dauernd initialisiert
yndaso - Di 23.12.08 12:08
Titel: form wird dauernd initialisiert
Hallo zusammen,
da ich c# Anfänger bin, steh ich nun an einem Problem an dem ich nicht mehr weiterkomme.
Ich hoffe mir kann hier
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| namespace Konfigurator { public partial class Form1 : Form { public Form1() { InitializeComponent(); this.lstOutput.Items.Add("text:"); MyClass _variable = new MyClass(); _MyClass.Aktion(); } private void btnSave_Click(object sender, EventArgs e) { ... } public void methode { ... } }
class MyClass { ... } |
Ich möchte/muss jetzt in MyClass die Methode "methode" aus der Hauptklasse form1 aufrufen.
Wenn ich direkt in MyClass die Methode aufrufe sagt der Comiler "Methode im Kontext nicht vorhanden"
was ja eigentlich auch stimmt.
So nun habe ich gedacht ich vererbe einfach die methode mit "class myClass : Form1".
Der Compiler meckert jetzt nicht mehr und ich kann auf die methode zugreifen, allerdings baut sich
mein Fenster nun nicht mehr auf. Im Einzelstep habe ich gesehen, dass ich in einer Endlosschleife
bin und immer "InitializeComponent()" ausgeführt wird.
Soo nun meine ich mal gelesen zu haben, dass man auch einen 2. Konstruktor anlegen kann, indem fall eben ohne
"InitializeComponent();".
Aber wie vererbt, bzw. selektiert man dann den 2. Konstruktor?
Bitte um Hilfe, grübel und googel bereits schon seit Stunden!
Danke im Voraus!
Moderiert von
Kha: C#-Tags hinzugefügt
JüTho - Di 23.12.08 13:06
Hallo,
Du solltest Dich wohl erst einmal mit Grundbegriffen befassen (hier stark vereinfacht und dadurch ungenau):
Klasse ist die Definition einer
Art von Dingen, enthaltend interne Elemente sowie öffentliche Eigenschaften und Methoden, die es bei dieser Art immer gibt.
Ein
Objekt/Instanz ist ein
spezielles Ding dieser Art. Normalerweise kann mit den (öffentlichen) Eigenschaften und Methoden nicht über die Klasse gearbeitet werden, sondern nur für ein spezielles Objekt.
Eine Klasse ist in der Regel public deklariert und wird mit dem Namen der Klasse angegeben, ggf. mit dem Namen einer Klasse, von der sie abgeleitet hat (d.h. deren öffentliche Elemente ebenfalls gelten sollen):
C#-Quelltext
1: 2: 3: 4:
| public class Automobile { ... } public class Truck : Automobile { ... } |
Alles, was zu dieser Klasse gehört, muss innerhalb des Blocks {...} stehen.
Ein internes
Element und eine dazugehörige
Eigenschaft werden z.B. so deklariert:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| private int numberOfWheels = 4; private Color color; public int NumberOfWheels { get { return numberOfWheels; } set { if (value >= 3) numberOfWheels = value; else throw new ArgumentOutOfRangeException("Ein Auto hat mindestens 3 Räder"); } } |
Eine
Methode wird gekennzeichnet durch die runden Klammern, in denen Argumente stehen, und einen Rückgabewert, der auch
void sein kann:
C#-Quelltext
1: 2: 3:
| public void ChangeColor(Color value) { this.Color = value; } |
Ein
Konstruktor ist eine spezielle Methode ohne Rückgabewert (denn es wird eine Instanz der betreffenden Klasse zurückgegeben):
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| public Automobile() { this.Color = Color.Black; }
public Automobile(Color defaultColor) { this.Color = defaultColor; } |
So, und jetzt vergleiche einmal die Konstruktion Deiner Klassen, nämlich von Form1 und MyClass, wozu gehört Methode, wo ist die Methode Aktion, und wie wird sie aufgerufen? Wozu dient die Variable _variable? Was willst Du eigentlich an welcher Stelle machen? (Konkrete Beschreibung, ggf. mit Pseudo-Code, wäre nützlich.)
Zur ausführlichen
Einführung verweise ich auf
OpenBook Visual C# [
http://openbook.galileocomputing.de/visual_csharp/].
Gruß und Frohe Weihnachten! Jürgen
PS. Bitte gewöhne Dir von Anfang aussagekräftige Bezeichner an. Namen wie MyClass und _variable gehören verboten; spätestens in zwei Wochen weißt auch Du nicht mehr, worum es geht (wobei mir klar ist, dass das bei einem solchen Anfangsbeispiel unwichtig ist).
yndaso - Di 23.12.08 13:20
JüTho hat folgendes geschrieben : |
PS. Bitte gewöhne Dir von Anfang aussagekräftige Bezeichner an. Namen wie MyClass und _variable gehören verboten; spätestens in zwei Wochen weißt auch Du nicht mehr, worum es geht (wobei mir klar ist, dass das bei einem solchen Anfangsbeispiel unwichtig ist). |
Ups! Die wirklichen Bezeichnungen sind anders, ich habe sie für den Beitrag hier nur abgeändert um es einfacher zu machen. Ist mir auch klar, dass ich bei den Bezeichnungen morgen nicht mehr weiß was gemeint ist..
Bei umbenennen ist mir ein Fehler unterlaufen, es heißt natürlich :
C#-Quelltext
1: 2:
| MyClass _variable = new MyClass(); __variable.Aktion(); |
Aber das ändert nichts an der Tatsache, dass sich die Anwendung nicht aufbaut
Moderiert von
Kha: Zitat gekürzt.
Moderiert von
Christian S.: C#-Tags hinzugefügt
JüTho - Di 23.12.08 13:28
yndaso hat folgendes geschrieben : |
Aber das ändert nichts an der Tatsache, dass sich die Anwendung nicht aufbaut |
Sorry, das hatte ich vergessen zu erwähnen: Weil der Code zu Aktion() und Methode() und zum Aufruf von Form1 fehlt, kann ich zu dieser "Hauptfrage" noch gar nichts sagen, nur viel und dumm rumraten.
Jürgen
yndaso - Di 23.12.08 13:47
JüTho hat folgendes geschrieben : |
yndaso hat folgendes geschrieben : | Aber das ändert nichts an der Tatsache, dass sich die Anwendung nicht aufbaut |
Sorry, das hatte ich vergessen zu erwähnen: Weil der Code zu Aktion() und Methode() und zum Aufruf von Form1 fehlt, kann ich zu dieser "Hauptfrage" noch gar nichts sagen, nur viel und dumm rumraten.
Jürgen |
Ich poste hier mal alles und diesmal tu ich auch nichts umeditieren:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134:
| namespace Konfigurator { public partial class Form1 : Form { public Form1() { InitializeComponent(); this.lstOutput.Items.Add("Found drives on sercos address:"); ScanSercos _SercAddr = new ScanSercos(); _SercAddr.ScanDrives(); } private void btnSave_Click(object sender, EventArgs e) { }
public void _opcSubscription_DataChanged(object subscriptionHandle, object requestHandle, ItemValueResult[] values) { if (this.InvokeRequired) { this.BeginInvoke(new DataChangedEventHandler(_opcSubscription_DataChanged), new object[] { subscriptionHandle, requestHandle, values }); return; } }
}
class ScanSercos : Form1 { private Opc.Da.Server _opcServer = null; private Opc.Da.Subscription _opcSubscription = null;
public void ScanDrives() { Opc.URL oUrl = new Opc.URL("opcda://localhost/OPC.IwSCP.1"); _opcServer = new Opc.Da.Server(new OpcCom.Factory(), oUrl); try { if (_opcServer != null && !_opcServer.IsConnected) { _opcServer.Connect(); } } catch (Exception ex) { MessageBox.Show(ex.Message); }
try { if (_opcServer.IsConnected) { Opc.Da.SubscriptionState state = new Opc.Da.SubscriptionState(); state.Active = true; state.ClientHandle = 123; state.Deadband = 0.0f; state.Name = "ScanSercos"; state.UpdateRate = 1000; _opcSubscription = (Opc.Da.Subscription)_opcServer.CreateSubscription(state); _opcSubscription.DataChanged += new DataChangedEventHandler(_opcSubscription_DataChanged); } else { throw new Exception("No connection to OPC Server! Could not create Group!"); } } catch (Exception ex) { MessageBox.Show(ex.Message); if (_opcServer.IsConnected) { _opcServer.Disconnect(); } } try { Opc.Da.Item[] opcItems = new Opc.Da.Item[2];
opcItems[0] = new Opc.Da.Item(); opcItems[0].ClientHandle = 1; opcItems[0].Active = true; opcItems[0].ItemName = "IndraMotion_MTX_P60,NC.MacodaParameter,100100001"; opcItems[0].ItemPath = ""; opcItems[1] = new Opc.Da.Item(); opcItems[1].ClientHandle = 1; opcItems[1].Active = true; opcItems[1].ItemName = "IndraMotion_MTX_P60,NC.MacodaParameter,105000004"; opcItems[1].ItemPath = "";
Opc.Da.ItemResult[] opcItemsResult = _opcSubscription.AddItems(opcItems); } catch (Exception ex) { MessageBox.Show(ex.Message); if (_opcServer.IsConnected) { _opcServer.Disconnect(); } } try { Opc.Da.Item[] opcItems = _opcSubscription.Items; Array opcValueArray = null; Array opcValueArray2 = null; Opc.Da.ItemValueResult[] opcItemValueResult = _opcSubscription.Read(opcItems); opcValueArray = opcItemValueResult[0].Value as Array; opcValueArray2 = opcItemValueResult[1].Value as Array; } catch (Exception ex) { MessageBox.Show(ex.Message); if (_opcServer.IsConnected) { _opcServer.Disconnect(); } } } }
} |
---------------------------------------------------------------------------------------------------
Ändere ich class ScanSercos : Form1
um auf class ScanSercos
So kommt eben die meldung das die Methode nicht vorhanden ist. Kommentier ich den aufruf auch noch aus, so startet das form dann schon, allerdings kann ich keine OPC items hinzufügen...
JüTho - Di 23.12.08 13:52
Ich werde erst dann genauer lesen, wenn der Code als C# markiert ist. Muss das denn immer ein Moderator nachholen? Bitte mitdenken und unter "Bereiche" das "C#" auswählen und den Plus-Button benutzen. Das kannst Du auch nachträglich erledigen! Jürgen
yndaso - Di 23.12.08 13:56
JüTho hat folgendes geschrieben : |
Ich werde erst dann genauer lesen, wenn der Code als C# markiert ist. Muss das denn immer ein Moderator nachholen? Bitte mitdenken und unter "Bereiche" das "C#" auswählen und den Plus-Button benutzen. Das kannst Du auch nachträglich erledigen! Jürgen |
Versteh schon, erzieherische Maßnahme. mach ich bei meinen Kindern auch so :-)
Aber als Neuling muss man das erstmal finden...
Habs geändert
JüTho - Di 23.12.08 17:39
yndaso hat folgendes geschrieben : |
Versteh schon, erzieherische Maßnahme. mach ich bei meinen Kindern auch so :-) |
Es geht doch nicht um eine erzieherische Maßnahme. Du möchtest Hilfe, aber erschwerst diese durch unleserliche Texte.
Auch jetzt passen die Einrückungen noch nicht richtig; aber das passiert auch durch das Kopieren vom Code-Editor in den Forums-Editor.
Wenn Du die Klasse ScanSercos von Form1 ableitest, passiert dieses: Application.Run erzeugt eine Instanz von Form1. Diese Instanz erzeugt eine Instanz von ScanSercos; dies ist eine Ableitung von Form1, also wird zuerst InitializeComponent von Form1 (als Basis von ScanSercos) aufgerufen, dann wird eine weitere (abhängige) Instanz von ScanSercos erzeugt. Auch diese Instanz ist eine Ableitung von Form1, also wird ... usw. Als Skizze:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| Program.cs Form1 => InitializeComponents() new ScanSercos : Form1 => InitializeComponents() new ScanSercos : Form1 => InitializeComponents() new ScanSercos : Form1 |
Verstehst Du jetzt dieses Problem?
Eine Ableitung von Form1 ist also zwangsläufig ein falsches Vorgehen.
Es bleibt also meine frühere Frage: Was sollen Methode() und Aktion() machen? Danach ist zu entscheiden, wohin sie gehören und wie die Zusammenarbeit zwischen ScanSercos und Form1 stattfinden soll. Klar ist momentan nur eins: ScanSercos darf nichts über Form1 wissen (insbesondere nicht über die ListBox oder was das ist); und Form1 holt "interne Informationen" aus der ScanSercos-Instanz vorzugsweise über Eigenschaften. Mehr möchte ich dazu aber noch spekulieren.
Gruß und Frohe Weihnachten! Jürgen
miniC# - Di 23.12.08 18:31
ich blicke durch den code da oben kaum durch, mir zu wirr :) allerdings glaube ich das problem verstanden zu haben, vielleicht hat
JüTho es schon geschrieben, aber der walloftext hier ist mir zu arbeitsintenisv in dieser besinnlichen zeit.
wenn du zwischen den beiden instanzen der beiden klassen (instanz von form und instanz von ScanSercos ) kommunizieren möchtest, dann solltest du der entsprechenden klasse einfach die instanz mitgeben :). ein guter ort dafür wäre der konstruktor. ein etwas sinnfreies beispiel :
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
| namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); r = new Random(); _myObj = new myClass(this); } private myClass _myObj; private Random r;
public void setCol() { _myObj.setBackColor (Color.FromArgb (255,(byte) r.Next (0,255), (byte) r.Next (0,255), (byte) r.Next (0,255))); }
private void button1_Click(object sender, EventArgs e) { this.setCol(); } }
public class myClass { public myClass(Form parent) { _parent = parent; }
private Form _parent;
public void setBackColor(Color color) { _parent.BackColor = color; } } } |
JüTho - Di 23.12.08 18:41
miniC# hat folgendes geschrieben : |
wenn du zwischen den beiden instanzen der beiden klassen (instanz von form und instanz von ScanSercos ) kommunizieren möchtest, dann solltest du der entsprechenden klasse einfach die instanz mitgeben :). |
Nein, bloß nicht! Was soll eine "sachbezogene Klasse" mit den Controls eines Formulars anfangen?
Ausführliche Erklärungen dazu stehen unter
Kommunikation zwischen 2 Forms [
http://www.mycsharp.de/wbb2/thread.php?threadid=5960] und den dortigen Hinweisen.
Jürgen
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!