| Autor |
Beitrag |
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Mo 27.01.03 19:32
Moin!
Ich habe drei verschiedene ComboBoxen auf meiner Form.
Wenn ich nun in der einen ein Item anwähle, sollen in dieser ComboBox die beiden, in den anderen ComboBoxen ausgewählten, Strings gelöscht werden.
Mein Problem:
Eigentlich sind in allen drei ComboBoxen diese acht Strings vorhanden:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| Walze Nr. I Walze Nr. II Walze Nr. III Walze Nr. IV Walze Nr. V Walze Nr. VI Walze Nr. VII Walze Nr. VIII |
Nur: In jeder der ComboBoxen sind immer nur 6 der Strings gleichzeitig zu finden, das die 2 restlichen ja in den jeweils anderen beiden ComboBoxen sind.
Soweit klar?
Wie bekommen ich nun heraus, an welcher Position z.B. der ausgewählte String der 1. ComboBox in der 2. ComboBox steht? Und wie kann ich ihn dort löschen?
Irgendwie blicke ich da nicht so ganz durch ... trotz Delphi-Hilfe! 
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Mo 27.01.03 19:37
Hattest Du dieses Problem nicht schon gelöst?
Naja, war wahrscheinlich irgendwas anderes und ich verwechsle das. Mit ComboBox1.Items.IndexOf(String) : Integer bekommst Du die Position dieses Strings in der ComoBox. Wenn Du als String die ausgewählten Elemente der anderen ComboBox benutzt, kannst Du mit Items.Delete den Rest erledigen.
MfG,
Peter
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Mo 27.01.03 19:41
Nö, du hast schon recht!
Jedenfalls dachte ich, es gelöst zu haben ... hab mich aber geirrt!
Thx für die schnelle Antwort. Ich werds gleich mal ausprobieren.
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Mo 27.01.03 20:06
Upps, merke gerade ich hab schon wieder einen Fehler gemacht!
Ich muss die in den beiden anderen ComboBoxen nicht in der letzten ComboBox, sondern in einer StringList löschen.
Wenn ich das so mache, dann funktioniert das Programm zwar, aber es werden die falschen Strings gelöscht:
| Zitat: | | StringList.Delete(ComboBox2.Items.IndexOf(ComboBox2.Items[TComboBox(Sender).ItemIndex])); |
Was mache ich falsch!?
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Mo 27.01.03 20:49
Ich gehe davon aus, dass Sender die ComboBox ist, in der etwas ausgewählt wurde und das ganze im OnChange-Ereignis steht.
Dann lässt Du Dir den Index des Items ausgeben, welches im Sender gerade ausgewählt wurde. Den Text zu diesem Item nimmst Du jedoch nicht von dem Sender, sondern von ComboBox2. Und ich glaube, dort liegt der Fehler, denn dadurch, dass Du aus verschiedenen ComboBoxen verschiedene Zeilen löschst, muss in verschiedenen ComboBoxen Zeilen mit gleicher Nummer nicht gleichen Text enthalten.
Es sollte:
Quelltext 1:
| ComboBox2.Items.Delete(ComboBox2.Items.IndexOf(TComboBox(Sender).Items[TComboBox(Sender).ItemIndex]))); |
Ob die Textzeile funktioniert, hängt natürlich von dem Quelltext ab, der drum herum steht. Machen soll sie folgendes:
Sie löscht, den Eintrag aus ComboBox2, der den gleichen Text enthält wie der Eintrag in der ComboBox "Sender", der gerade dort (in ComboBox "Sender") ausgewählt wurde. Man ist das kompliziert zu formulieren!
MfG,
Peter
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Mo 27.01.03 21:11
Erstmal: Wieso verwirrst du mich so!? *heul*
Deine Lösung funktioniert nicht ... weil du mich (meiner Meinung nach) nicht verstehst.
Also:
Ich erzeuge eine StringList und lade dort alle 8 Strings herein, die in den ComboBoxen enthalten sein könnten. In jeder ComboBox sin djeweils nur 6 Strings enthalten.
Wenn ich nun in ComboBox1 einen String auswähle, dann sollen in der StringList die beiden ausgewählten Strings der 2 anderen ComboBoxen gelöscht werden. Die restlichen 6 Strings werden in die ComboBox1 geladen. Gleichzeitig muss ín den beiden andern ComboBoxen der in ComboBox1 ausgewählte String gelöscht werden.
PS: Da Ereignis ist OnChange!
... Hoffe, alles ist drin.
Hier mein momentaner Quellcode (das der ausgewählte String in den anderen 2 ComboBoxen auch gelöscht wird, ist noch nicht eingebaut!):
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:
| procedure TForm1.WalzenAuswahl(Sender: TObject); var i, WalzenNummer : Integer; AusgewaehlteWalze : String; begin AlleReflektoren := 'YRUHQSLDPXNGOKMIEBFZCWVJATFVPJIAOYEDRZX WGCTKUQSBNMHL'; AlleWalzen := 'EKMFLGDQVZNTOWYHXUSPAIBRCJAJDKSIRUXBLHWTM CQGZNPYFVOEBDFHJLCPRTXVZNYEIWGAKMUSQOESOVPZJAYQUIRHXL NFTGKDCMWBVZBRGITYUPSDNHLXAWMJQOFECKJPGVOUMFYQBENHZR DKASXLICTWNZJHGRCXMYSWBOUFAIVLPEKQDTFKQHTLXOCBJSPDZR AMEWNIUYGV'; if TComboBox(Sender).Name = 'AuswahlReflektor' then for i := 1 to 26 do Reflektor[i] := AlleReflektoren[i + 26 * AuswahlReflektor.ItemIndex] else begin AngezeigteWalzen := TStringList.Create; try AngezeigteWalzen.LoadFromFile('WalzenListe.txt'); TComboBox(Sender).Items := AngezeigteWalzen; AusgewaehlteWalze := TComboBox(Sender).Items[TComboBox(Sender).ItemIndex]; WalzenNummer := AngezeigteWalzen.IndexOf(AusgewaehlteWalze); if TComboBox(Sender).Name = 'AuswahlWalze1' then begin AngezeigteWalzen.Delete(AuswahlWalze1.Items.IndexOf(AuswahlWalze1.Items[TComboBox(Sender).ItemIndex])); AngezeigteWalzen.Delete(AuswahlWalze2.Items.IndexOf(AuswahlWalze2.Items[TComboBox(Sender).ItemIndex])); for i := 1 to 26 do Walze1[i] := AlleWalzen[i + 26 * WalzenNummer]; end;
if TComboBox(Sender).Name = 'AuswahlWalze2' then begin AngezeigteWalzen.Delete(AuswahlWalze1.Items.IndexOf(AuswahlWalze1.Items[TComboBox(Sender).ItemIndex])); AngezeigteWalzen.Delete(AuswahlWalze3.Items.IndexOf(AuswahlWalze3.Items[TComboBox(Sender).ItemIndex])); for i := 1 to 26 do Walze2[i] := AlleWalzen[i + 26 * WalzenNummer]; end;
if TComboBox(Sender).Name = 'AuswahlWalze3' then begin AngezeigteWalzen.Delete(AuswahlWalze1.Items.IndexOf(AuswahlWalze1.Items[TComboBox(Sender).ItemIndex])); AngezeigteWalzen.Delete(AuswahlWalze2.Items.IndexOf(AuswahlWalze2.Items[TComboBox(Sender).ItemIndex])); for i := 1 to 26 do Walze3[i] := AlleWalzen[i + 26 * WalzenNummer]; end; TComboBox(Sender).ItemIndex := TComboBox(Sender).Items.IndexOf(AusgewaehlteWalze); finally AngezeigteWalzen.Free; end; end; end; |
Wie bekomme ich das hin?
Oder was mache ich falsch?
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Mo 27.01.03 21:30
Sollte ich Dich tatsächlich richtig verstanden haben, würde ich es so machen:
Am Anfang ist bei jeder ComboBox ein Item ausgewählt. Außerdem hast Du alle acht Items in einer StringList gespeichert.
Nun wird in (z.B.) ComboBox1 ein neues Item ausgewählt. Dort muss an den Items sonst nichts geändert werden, es muss nur das entsprechende Ereignis ausgelöst werden.
Das Ereignis macht folgendes:
Teil 1:
1. Es speichert den Text von dem Item, welches gerade in ComboBox2 ausgewählt ist in einer Variable ("item_temp : STRING").
2. Es löscht alle Items aus ComboBox2 und lädt diese Items neu und zwar aus der StringList.
3. Aus ComboBox2 werden jene Items gelöscht, die in ComboBox1 und ComboBox3 ausgewählt wurden. (Mit IndexOf und Delete einfach zu machen.)
4. Mit Hilfe von IndexOf und item_temp wird nun der Index des Items gefunden, welches am Anfang in ComboBox2 ausgewählt war. Auf diesen Index wird ItemIndex nun gesetzt, damit dieses Item auch wieder ausgewählt ist.
Teil 2: das gleiche für ComboBox3 anstatt ComboBox2.
Probleme, die auftauchen könnten: es könnte sein, dass in Schritt 4 das OnSelect-Ereignis von ComboBox2 ausgelöst wird. Das könnte zu einer Endlosschleife führen. Du solltest in einer globalen Variable speichern, dass Du gerade nur die Items aktualisierst und die OnSelect-Ereignisse der Boxen nichts unternehmen sollen.
Ich hoffe, ich konnte Dir helfen.
MfG,
Peter
P.S.: Keine Ahnung, ob das, was ich geschrieben habe, klappt. Konnte es ja nicht selbst testen.
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Di 28.01.03 18:36
Du hast mich nicht richtig verstanden! (Wenn ich dich richtig verstehe  )
Aber ich glaube, mit einem Beispiel als Ergänzung, kann ich es dir besser erklären, als wenn ich es hier nur beschreiben sollte:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| MyComboBox1 MyComboBox2 MyComboBox3 Walze Nr. III Walze Nr. VII Walze Nr. I
Walze Nr. II Walze Nr. II Walze Nr. I Walze Nr. III Walze Nr. IV Walze Nr. II Walze Nr. IV Walze Nr. V Walze Nr. IV Walze Nr. V Walze Nr. VI Walze Nr. V Walze Nr. VI Walze Nr. VII Walze Nr. VI Walze Nr. VIII Walze Nr. VIII Walze Nr. VIII
MyComboBox1 MyComboBox2 MyComboBox3 Walze Nr. VIII Walze Nr. VII Walze Nr. I
Walze Nr. II Walze Nr. II Walze Nr. I Walze Nr. III Walze Nr. III Walze Nr. II Walze Nr. IV Walze Nr. IV Walze Nr. III Walze Nr. V Walze Nr. V Walze Nr. IV Walze Nr. VI Walze Nr. VI Walze Nr. V Walze Nr. VIII Walze Nr. VII Walze Nr. VI |
Ich habe also in der MyComboBox1 die ausgewählte Walze geändert.
Im OnChange-Ereignis sollen dann folgende Dinge gemacht werden:
1. In den Variablen ItemTemp1, ItemTemp2 und ItemTemp3 werden die in MyComboBox1, MyComboBox2 und MyComboBox3 ausgewählten Items gespeichert.
2. MyStringList wird mit allen zur Verfügung stehenden Walzen geladen.
3. Aus MyStringList werden die beiden in MyComboBox2 und MyComboBox3 ausgewählten Items gelöscht.
4. MyComboBox1.Items wird mit MyStringList geladen.
5. Für MyComboBox2 und MyComboBox3 werden die Schritte 2 bis 4 ausgeführt.
6. MyComboBox1.ItemIndex wird mit der Position von ItemTemp1 in MyComboBox1 geladen.
7. Schritt 6 wird für MyComboBox2 und MyComboBox3 ausgeführt.
Und hier jetzt der Quellcode:
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:
| var Walze1: String = 'BDFHJLCPRTXVZNYEIWGAKMUSQO'; Walze2: String = 'NZJHGRCXMYSWBOUFAIVLPEKQDT'; Walze3: String = 'EKMFLGDQVZNTOWYHXUSPAIBRCJ'; MyStringList : TStrings;
...
procedure TForm1.WalzenAuswahl(Sender: TObject); var i : Integer; ItemTemp1, ItemTemp2, ItemTemp3 : String; begin AlleWalzen := 'EKMFLGDQVZNTOWYHXUSPAIBRCJAJDKSIRUXBLHWTMCQGZNPYFVOE BDFHJLCPRTXVZNYEIWGAKMUSQOESOVPZJAYQUIRHXLNFTGKDCMWB VZBRGITYUPSDNHLXAWMJQOFECKJPGVOUMFYQBENHZRDKASXLICTW NZJHGRCXMYSWBOUFAIVLPEKQDTFKQHTLXOCBJSPDZRAMEWNIUYGV
MyStringList.Create; try
ItemTemp1 := MyComboBox1.Items[MyComboBox1.ItemIndex]; ItemTemp2 := MyComboBox2.Items[MyComboBox2.ItemIndex]; ItemTemp3 := MyComboBox3.Items[MyComboBox3.ItemIndex];
MyStringList.LoadFromFile('E:\Informatik\Delphi-Programme\M.F.A Enigma\Enigma\WalzenListe.txt'); MyStringList.Delete(MyComboBox1.Items.IndexOf(ItemTemp2)); MyStringList.Delete(MyComboBox1.Items.IndexOf(ItemTemp3)); MyComboBox1.Items := MyStringList;
MyStringList.LoadFromFile('E:\Informatik\Delphi-Programme\M.F.A Enigma\Enigma\WalzenListe.txt'); MyStringList.Delete(MyComboBox2.Items.IndexOf(ItemTemp1)); MyStringList.Delete(MyComboBox2.Items.IndexOf(ItemTemp3)); MyComboBox2.Items := MyStringList;
MyStringList.LoadFromFile('E:\Informatik\Delphi-Programme\M.F.A Enigma\Enigma\WalzenListe.txt'); MyStringList.Delete(MyComboBox3.Items.IndexOf(ItemTemp1)); MyStringList.Delete(MyComboBox3.Items.IndexOf(ItemTemp2)); MyComboBox3.Items := MyStringList;
for i := 1 to 26 do Walze1[i] := AlleWalzen[i + 26 * MyComboBox1.Items.IndexOf(ItemTemp1)]; for i := 1 to 26 do Walze2[i] := AlleWalzen[i + 26 * MyComboBox2.Items.IndexOf(ItemTemp2)]; for i := 1 to 26 do Walze3[i] := AlleWalzen[i + 26 * MyComboBox3.Items.IndexOf(ItemTemp3)];
MyComboBox1.ItemIndex := MyComboBox1.Items.IndexOf(ItemTemp1); MyComboBox2.ItemIndex := MyComboBox2.Items.IndexOf(ItemTemp2); MyComboBox3.ItemIndex := MyComboBox3.Items.IndexOf(ItemTemp3);
finally MyStringList.Free; end;
end; |
Das Programm bringt keine Fehlermeldung und startet auch. Nur wenn ich nun eine neue Walze in einer der ComboBoxen auswähle, kommt folgende Meldung:
| Zitat: | | Project P_Enigma.exe raised exeption class EActionViolation with message ''Access violation azt address 0040384D in module 'P_ENIGMA.EXE'. Read of address FFFFFFFF'. Process stopped. Use step or Run to continue. |
Verstehst du nun, was passieren soll, wenn ich eine andere Walze in einer der ComboBoxen auswähle?
Wa mache ich falsch bzw. wo liegt der Fehler?
 *verzweifel* 
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Di 28.01.03 18:56
| Zitat: | Im OnChange-Ereignis sollen dann folgende Dinge gemacht werden:
1. In den Variablen ItemTemp1, ItemTemp2 und ItemTemp3 werden die in MyComboBox1, MyComboBox2 und MyComboBox3 ausgewählten Items gespeichert.
2. MyStringList wird mit allen zur Verfügung stehenden Walzen geladen.
3. Aus MyStringList werden die beiden in MyComboBox2 und MyComboBox3 ausgewählten Items gelöscht.
4. MyComboBox1.Items wird mit MyStringList geladen.
5. Für MyComboBox2 und MyComboBox3 werden die Schritte 2 bis 4 ausgeführt.
6. MyComboBox1.ItemIndex wird mit der Position von ItemTemp1 in MyComboBox1 geladen.
7. Schritt 6 wird für MyComboBox2 und MyComboBox3 ausgeführt. |
Irgendwie scheinst Du mein letztes Posting nicht sehr aufmerksam gelesen zu haben. Denn mein Vorschlag für das, was im OnChange-Ereignis passieren soll, läuft auf genau das gleiche hinaus.
Nun zu Deinem Programm. Wo der Fehler genau liegt, weiß ich nicht und ich habe auch keine Lust das ganze bei mir auszuprobieren. Am besten gehst Du einfach mal die Einzelschritte zur Laufzeit durch und schaust Dir an, wie sich die Variablen verändern.
Aber noch ein paar Sachen, die mir aufgefallen sind:
MyStringList.Delete(MyComboBox1.Items.IndexOf(ItemTemp2));Du beziehst den Index des zu löschenden Items aus der ComboBox1, löschst aber aus MyStringList. Da ComboBox1 immer zwei Items weniger enthält als eine frisch geladene MyStringList, werden die Indizes nicht zu einander passen. Entsprechend bei den anderen Delete-Anweisungen.
MyComboBox1.Items := MyStringList;Damit erzeugst Du nur eine Referenz von ComboBox1.Items zu MyStringList. Du solltest zuerst einmal alle Items aus der ComboBox lösche und dann mit ComboBox1.Items.Assign(MyStringList) (oder so...) neu laden. Sonst kann es da zu unerwünschten Effekten kommen.
Quelltext 1:
| MyComboBox1.ItemIndex := MyComboBox1.Items.IndexOf(ItemTemp1); |
Ich bin mir nicht sicher, ab das könnte erneut ein OnSelect-Ereignis auslösen, was Dir evtl. eine Endlosschleife beschert.
| Zitat: | | Verstehst du nun, was passieren soll, wenn ich eine andere Walze in einer der ComboBoxen auswähle? |
Das hatte ich, glaube ich, schon vorher verstanden. Siehe mein letztes Posting.
MfG,
Peter
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Sa 01.02.03 10:19
Leider bin ich gerade erst wieder dazu gekommen meine Enigma weiter zu programmieren.
Und da habe ich einfach mal (billiges bewährt sich halt immer wieder) in der procedure TForm1.WalzenAuswahl(Sender: TObject); überall ShowMessages reingepackt, um zu gucken wie weit die Prozedur kommt, bis sie sich aufhängt.
Und siehe da: sie kommt nicht mal zur Initialisierung der StringList!
Woran lags?
Quelltext 1: 2: 3: 4: 5:
| MyStringList.Create;
{muss werden zu}
MyStringList := TStringList.Create; |
Dann klappst auch mit dem Nachbarn! 
|
|
Ist die Frage beantwortet? Das Problem gelöst?
Dann klicke hier, um das Thema entsprechend zu markieren!
|
|