Entwickler-Ecke
WinForms - Kommunikation zwischen der Formen
Raorkon - Fr 24.06.11 12:24
Titel: Kommunikation zwischen der Formen
Hallo Zusammen,
ich habe ein seltsames Problem:
ich habe eine Form die eine Hardware initalisiert und das dabei auch Werte über ein Event zurückgibt:
C#-Quelltext
1: 2: 3:
| EventHandler evt = new EventHandler(this.BarcodeReader_OnRead); SingletonProvider<Symbol_Class>.Instance.AttachReadNotify(evt); |
soweit so gut, funktioniert auch tadellos
nun wird aus dieser Form ein Menü aufgerufen
C#-Quelltext
1: 2: 3: 4: 5:
| MainForm mainForm = new MainForm(); BarcodeReaderDeregisterMethods(); mainForm.ShowDialog(); |
nun rufe ich aus dem Menü heraus eine weitere Form auf
C#-Quelltext
1: 2: 3:
| Form blub= new Form(); blub.ShowDialog(); |
in der Form weise ich ebenfalls wieder events zu
C#-Quelltext
1: 2: 3:
| EventHandler evt = new EventHandler(this.BarcodeReader_OnRead); SingletonProvider<Symbol_Class>.Instance.AttachReadNotify(evt); |
und da habe ich mein Problem:
denn sobald das Event in der blub Form ausgeführt werden soll, passiert gar nichts.
D.h. mein zugewiesenes Event wird nicht beachtet bzw. die Methode wird nicht angesprochen.
Sobald ich wieder die 3. und 2. Form schliesse, wird mein Event (aus Form 3) ausgeführt in der Methode der 1.Form.
was ich schon rausgefunden habe ist folgendes:
Sobald ich die Form 1 dispose funktioniert auch das Event aus Form 3.
Nur ist das keine Alternative für mich da ich in der 1.Form unter anderem den Singleton intialisiere und auch noch einige andere wichtige Programmparameter setze. Ausserdem will ich der Ursache auf den Grund gehen.
ich hoffe ich habe mich halbwegs verständlich ausgedrückt.
Thx für eure Hinweise
Th69 - Fr 24.06.11 15:59
Hallo Raorkon,
ein wenig schwierig, dir eine konkrete Antwort zu geben, da dies verschiedene Ursachen haben könnte.
Als erstes tippe ich mal auf ShowDialog (bzw. das zweifache Aufrufen davon). Ändere mal testweise dies in einen einfachen Show()-Aufruf um.
In welcher Methode führst du denn den ShowDialog()-Aufruf durch, im Konstruktor oder in der Form.Load()-Ereignismethode?
Und dann ist nicht klar, was genau die SingletonProvider<Symbol_Class>.Instance.AttachReadNotify()-Methode macht. Registriert diese nur den Event? Und welche Klasseninstanz führt dann konkret diese Events aus?
Außerdem habe ich noch meinen eigenen Artikel zur
Kommunikation von 2 Forms [
http://www.bitel.net/dghm1164/programming/Kommunikation_von_2_Forms.html], der dir evtl. weiterhelfen könnte...
Raorkon - Fr 24.06.11 18:18
Hallo TH69,
in der ersten Form initalisiere ich den Barcodescanner z.B. dort wird festgelegt welchen Barcode gescannt werden soll.
Ausserdem wird in der ersten Form die Möglichkeit geben, das man sich Tasteneingabe oder per Scanner eines Barcodes anmelden kann.
das mach ich alles im Load-Event der Form1
In der 2.Form soll nicht gescannt werden, d.h. dort wird dem Scanner auch keinem Event zugeordnet
in der 3.Form soll wieder gescannt werden, dafür habe ich dann in dem Load-Event der Form auch die Methode
BarcodeReaderRegisterMethods() aufgerufen.
Diese Methode habe ich in jeder Klasse definiert.
In den beiden Formen 1 und 3 gibt es die Methode BarcodeReader_OnRead, in dieser Methode werden spezielle Berechnung durchgeführt die in den Formen sehr unterschiedlich sind.
In der Form1 wird in dieser Methode auch die Anmeldedaten geprüft, bei positiver Prüfung die Methode 2 aufgerufen.
Das Deregistrien der Events für den Scanner mach ich in der Form3 im Closing-Event.
//so das ist im groben die erste Form
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: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162:
| private void LogOnForm_Closing(object sender, CancelEventArgs e) { if (!appCanBeClosed) { e.Cancel = true; }
BarcodeReaderDeregisterMethods(); SingletonProvider<Symbol_Class>.Instance.TermReader(); }
private void LogOnForm_Load(object sender, EventArgs e) { BarcodeReaderInit(); BarcodeReaderRegisterMethods(); SingletonProvider<Symbol_Class>.Instance.StartRead(); }
private void BarcodeReaderInit() { try { SingletonProvider<Symbol_Class>.Instance.InitReader(); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
private void BarcodeReaderRegisterMethods() { EventHandler evt = new EventHandler(this.BarcodeReader_OnRead); SingletonProvider<Symbol_Class>.Instance.AttachReadNotify(evt);
EventHandler _evt = new EventHandler(this.myReader_StatusNotify); SingletonProvider<Symbol_Class>.Instance.AttachStatusNotify(_evt); }
private void myReader_StatusNotify(object Sender, EventArgs e) { Symbol.Barcode.BarcodeStatus TheStatusData = SingletonProvider<Symbol_Class>.Instance.Reader.GetNextStatus();
if (TheStatusData.State == States.READY || TheStatusData.State == States.IDLE) scannerstatus = true; else scannerstatus = false;
}
private void BarcodeReaderDeregisterMethods() { SingletonProvider<Symbol_Class>.Instance.StopRead(); SingletonProvider<Symbol_Class>.Instance.DetachReadNotify(); SingletonProvider<Symbol_Class>.Instance.DetachStatusNotify(); }
private void BarcodeReader_OnRead(object sender,EventArgs e) { ReaderData readerData = null;
if (!scannerstatus) return; try { SingletonProvider<Symbol_Class>.Instance.StopRead(); readerData = SingletonProvider<Symbol_Class>.Instance.Reader.GetNextReaderData(); } catch(Exception ex) { MessageBox.Show(ex.Message); return; }
txtScannedEmployeeId.Text = readerData.Text;
readerData = null;
SqlCeDatabase MyDatabase = new SqlCeDatabase(SingletonProvider<Global>.Instance.SqlConnectionString);
bool UserIsOK = MyDatabase.VerifyUserID(txtScannedEmployeeId.Text); SingletonProvider<Symbol_Class>.Instance.StartRead(); if (UserIsOK == true) { stbMainForm.Text = String.Empty; this.textBox1.Text = MyDatabase.GetUserNameFromID(txtScannedEmployeeId.Text); LogOn(txtScannedEmployeeId.Text); } else { stbMainForm.Text = Strings.WARN_EMPLOYEEID_SCAN_WRONG; this.textBox1.Text = string.Empty; } MyDatabase = null; }
private void LogOn(String bcEmployeeID) {
Cursor.Current = Cursors.WaitCursor; MainForm mainForm = new MainForm(); syData.userid = bcEmployeeID; try { BarcodeReaderDeregisterMethods(); mainForm.ShowDialog(); } catch (Exception ex) { MessageBox.Show(ex.Message); }
mainForm.Dispose();
Cursor.Current = Cursors.Default;
BarcodeReaderRegisterMethods(); SingletonProvider<Symbol_Class>.Instance.StartRead(); txtScannedEmployeeId.Focus(); } |
die Klasse Symbol sieht im auszugsweise so aus:
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:
| public void AttachReadNotify(System.EventHandler ReadNotifyHandler) { if( Scanner != null) { Scanner.ReadNotify += ReadNotifyHandler; myReadNotifyHandler = ReadNotifyHandler;
} }
public void DetachReadNotify() { try { if ((Scanner != null) && (myReadNotifyHandler != null)) { Scanner.ReadNotify -= myReadNotifyHandler; myReadNotifyHandler = null; } } catch (Exception ex) { } }
public void AttachStatusNotify(System.EventHandler StatusNotifyHandler) { if (Scanner != null) { Scanner.StatusNotify += StatusNotifyHandler; myStatusNotifyHandler = StatusNotifyHandler; } }
public void DetachStatusNotify() { try { if ((Scanner != null) && (myStatusNotifyHandler != null)) { Scanner.StatusNotify -= myStatusNotifyHandler; myStatusNotifyHandler = null;
} } catch (Exception ex) { } } |
Th69 - Sa 25.06.11 08:48
Hallo und guten Morgen Raorkon,
ok, der Scanner-Instanz (innerhalb der Klasse Symbol) werden also die Event-Methoden zugewiesen.
Wer jedoch ruft die Scanner-Methoden auf? Laufen diese in einem eigenen Thread?
Und kannst du diese dann debuggen?
BTW: dies ist mein 1000. Beitrag hier im Forum - juhu :dance2:
Raorkon - Sa 25.06.11 10:26
Guten morgen und Glückwunsch und ich fühle mich geehrt das du deinen 1000. Beitrag für mich geschrieben hast :D
die Scanner sind mit einem SDK eingebunden (Symbol), heißt ich kann diese auch nicht debuggen.
die Events werden auch zugewiesen das habe ich mehrmalig geprüft. Ich denke aber nicht das es ein Fehler des SDKs ist, denn wenn ich
die 1.Form dispose dann kann ich auch problemlos in der 3., 4.... Form scannen, jedoch muss ich jede Form in der ich gescannt habe schliessen.
Es gab auch einen Beispielcode von Symbol, aus diesen habe ich mir die Klasse Symbol erstellt. Einzigster Unterschied sind die Aufrufe des GC die ich nicht duchführe, das hat aber keinen Unterschied gemacht und aus den Postings die ich hier gelesen habe ist es eh nicht notwendig.
Ach ja wenn ich in der 1. Form nicht scanne, d.h. wenn ich den Event nicht auslöse, kann ich auch in der 3.Form scannen.
Oder sollte es doch am SDK liegen?
Th69 - Sa 25.06.11 13:19
Hallo,
ja ich denke, das wird das Zusammenspiel des SDKs mit deinen 3 modalen Dialogen sein.
Jeder Aufruf per ShowDialog erzeugt eine eigene Message-Loop, anstatt daß nur die eine Message-Loop vom Application.Run() benutzt wird. Dies kann gerade in Verbindung mit externen SDKs Probleme bereiten (ich nehme mal an, daß das Scanner-SDK nativ in C bzw. C++ und nicht mit .NET-Mitteln programmiert wurde).
Darum habe ich als erstes ja auch geschrieben, daß du mal testweise mit Show() die Aufrufe durchführen solltest.
Du könntest ja ein pseudo-modales Verhalten simulieren, indem du das Close-Event abonnierst und vor dem Aufruf einfach die eigene Form deaktivierst (this.Enabled = false) und dann in der Close-Eventmethode dann diese wieder aktivierst.
Raorkon - Sa 25.06.11 15:29
okay dank dir für den Typ, werde ich nächste Woche gleich mal ausprobieren, Sobald ich ein Ergebnis habe melde ich mich
Raorkon - Mo 04.07.11 05:57
Hallo,
sorry erstmal für die späte Antwort, aber ein anderes Projekt hatte ersteinmal vorrang.
ich habe das Problem wie vorgeschlagen gelöst, in dem ich die Mainmaske mti Show() usw. aufgerufen habe.
Danke für deine Hinweise und Hilfe
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 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!