Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - ComboBox und Items "sperren"
Anonymous - Sa 07.12.02 11:12
Titel: ComboBox und Items "sperren"
Hei!
Ich habe drei ComboBoxen mit demselben Inhalt auf der Form. Sagen wir mal es sind die Zahlen 1-8.
Wird nun in einer ComoBox die Zahl 3 ausgewählt, so soll diese in allen ComoBoxen "gesperrt" werden.
Das möchte ich so machen, wie bei einem Hauptmenu, wo die gesperrten Items dann grau sind.
Nur weiss ich nicht wie das gehen soll!
Ich kenne zwar die Möglichkeit über ComboBox.Items.Delete und ComboBox.Items.Insert das ausgewählte Item zu löschen und wieder einzufügen, aber das ist für mein Programm ein bisschen zu aufwendig, weil der Quellcode nur eine bestimmte Länge haben darf. Und diese Möglichkeit scheint mir sehr aufwendig zu sein.
Bitte um Hilfe!
MfG
Dope | Fish
Anonymous - Sa 07.12.02 17:43
Es gibt die Möglichkeit das Item in Verwendung grau zu zeichnen. Allerdings hast du jetzt schon Problem mit deinen Kentnissen das Feld zu sperren. Wenn ich mich also auf eine Diskusion einlasse, dann endet es damit, daß ich es selbst programmieren muß. Leider hab ich momentan dafür zu wenig Zeit. Wenn du es aber selbst versuchen willst, dann heißt das Stichwort
OnDrawItem. Du muß die Kontrolle über die ComboBox übernehmen und alles selbst zeichen.
Alternative 2:
Du speicherst deine Liste ( z.B. Zahlen 1-8 ) in eine TStringList. Diese kannst du an jede Combobox über:
Quelltext
1:
| ComboBox.Items.Text := StringList.Text |
übregeben. D.h. du kannst mit Delete in deiner Combobox das Item in Verwendung löschen. Bei jedem OnEnter übergibst du zuerst StringList.Text an die Combobox und löscht dann die beiden Zahlen die von den anderen benutzt werden. Auf diese Weise bleibt deine ComboBox immer aktuell.
Alternative 3:
Du löscht garnichts. Allerdings plazierst du vor dem bereits benutztem Zeichen ein *. Der Nutzer sieht dann, daß er das Zeichen nicht mehr nehmen darf. Sollte er es dennoch tun, denn kannst du bei OnChange prüfen ob das neugewählte Zeichen mit einem Stern anfängt. Wenn ja, dann ignorierst du die Änderung. Ansonsten bleibt alles beim Alten (d.h. Alternative 2). Bei jedem OnEnter entfernst du zuerst die * vor den Zeichen. Dann prüfst du aufs neue welche Zahlen von den beiden Anderen benutzt werden und setzt ein Stern davor.
Christian S. - Sa 07.12.02 18:46
Hi!
Also, nachdem Popov gesagt hat, wie es geht, bin ich jetzt auch dahinter gestiegen. Wieso bin ich da nicht früher drauf gekommen?
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); begin ComboBox1.Canvas.FillRect(Rect); if index = 3 then ComboBox1.Canvas.Font.Color:=clGray; ComboBox1.Canvas.TextOut(Rect.Left,Rect.Top,ComboBox1.Items[index]); if index = 3 then ComboBox1.Canvas.Font.Color:=clBlack; end; |
Außerdem den Stil auf csOwnerDrawFixed stellen!
Damit wird das dritte Item grau gezeichnet, sonst alle schwarz. Jetzt musst Du nur noch irgendwie verhindern, dass das graue Item auch ausgewählt werden darf, aber das ist ja nicht schwer.
MfG,
Peter
Anonymous - Sa 07.12.02 20:25
Das wollte ich gerade nicht. Es ist nicht unmöglich zu bestimmen welche Items in Benutzung sind, allerdings nicht über das graue Feld. Dieses ist nur gezeichnet. Auch kann man sich nirgendwo notieren welche jetzt in Benutzung sind, da es mehrere sein können. Er muß also jedes mal nach der Auswahl zuerst in den anderen ComboBoxen prüfen ob die da in Benutzung sind. Es ist also für einen Anfänger wesentlich schwerer als die Alternativen. Allerdings ist es nicht unmöglich.
Christian S. - Sa 07.12.02 20:31
Was Du nicht wissen kannst: es geht um
dieses [
http://www.auq.de/viewtopic.php?t=3773] Programm und in diesem Rahmen ist es nicht allzu schwer. Außerdem ist es durchaus möglich, die Nummern der verwendeten Items in einem Array zu speichern und dann darin nachzuschauen. Das ist auch für einen Anfänger (und D0P3 F!$H ist kein blutiger Anfänger mehr) möglich. Und wie Du in oben genanntem Thread siehst, bin ich durchaus bereit, da zu helfen.
MfG,
Peter
Anonymous - Sa 07.12.02 21:39
Zitat: |
Wenn ich mich also auf eine Diskusion einlasse, dann endet es damit, daß ich es selbst programmieren muß. |
Das kannst du gleich sein lassen! Nicht das ich an dir zweifel, aber ich muss den KOMPLETTEN Quellcode verstehen bzw. meinem Lehrer verständlich machen ... und da weiss ich nicht, was schwieriger ist. :twisted:
Selbst zeichnen könnte ich es natürlich, aber ob ich das hinkriege oder ob das dann nicht den Quellcode "sprengen" würde, weiss ich ehrlich gesagt nicht.
Und wenn du in etwa das damit meinst, was Peter gepostet hat, dann vergessen wir das mal schnell wieder! Denn wie du gesagt hast, soll es schwierig sein, das graue Feld zu finden.
Aber nach Peters letztem Posting solltet ihr euch mal kurz schliessen, weil ich bei einem Gespräch auf einen intellektuell so hohen Ebene mit euch Genies nicht mehr mithalten kann! 8)
Zitat: |
Bei jedem OnEnter übergibst du zuerst StringList.Text an die Combobox |
Das hört sich doch einfach an (also kann ich das wohl auch programmieren)!
Auch Alternative 3 hört sich gut an. Da muss ich gucken, ob A2 oder A3 besser ist.
Zitat: |
und D0P3 F!$H ist kein blutiger Anfänger mehr |
:oops: Das hast du schön gesagt. Danke! :oops:
Und das, nachdem ich dich so alt gemacht hab!
Womit hab ich das verdient! :oops:
Christian S. - Sa 07.12.02 22:21
Zitat: |
Und wenn du in etwa das damit meinst, was Peter gepostet hat, dann vergessen wir das mal schnell wieder! Denn wie du gesagt hast, soll es schwierig sein, das graue Feld zu finden. |
Das ist nicht schwer! Für Dein spezielles Problem sogar sehr einfach! Du hast ja nicht soviele Boxen zu überprüfen. Dort, wo bei mir "if index=3" steht, muss bei Dir sowas in dem Stil von "if (index=Walze1.ItemIndex) OR (index=Walze2.ItemIndex)" stehen. Mehr braucht es eigentlich nicht. Und wenn dann jemand ein Item auswählen will, prüftst Du halt noch einmal nach, welche NUmmer er auswählen will, und ob er das darf. Das bekommen wir in noch nicht einmal einer Seite Posting hin.
Zitat: |
Das hast du schön gesagt. Danke!
Und das, nachdem ich dich so alt gemacht hab!
Womit hab ich das verdient! |
Aber gern geschehen. Du hast doch schon ziemlich viel gelernt, oder? Und ich hoffe mal, dass Du auch freiwillig weiter machst, wenn Dein Projekt fertig ist.
MfG,
Peter
Anonymous - Sa 07.12.02 22:42
Werd mir das morgen mal genauer ansehen und dann im Laufe des TAges posten, was rausgekommen ist.
Zitat: |
Du hast doch schon ziemlich viel gelernt, oder? Und ich hoffe mal, dass Du auch freiwillig weiter machst, wenn Dein Projekt fertig ist. |
Jupp, hab ich! :D
Aber bei den Lehrern auch kein Wunder! *+1000 Schleimpunkte*
Mein Projekt wollte ich solange weitermachen, bis es wie die echte Enigma funktioniert ... koste es was es wolle!
Und außerdem muss ja auch noch einem Freund bei seinem Projekt helfen und ich progge auch sonst öfters mal, wenn mir was Gutes einfällt.
Anonymous - So 08.12.02 18:55
Wahrscheinlich bin ich nur zu blöd, aber ...
Ich habe es erstmal mit "*" davor und dahinter versucht. Hat auch geklappt, nur war nach der Auswahl das ComboBoxfeld, wo dann ja eigentlich der markierte Eintrag stehen sollte, zwar markiert, aber leer.
Dann habe ich es mit StringList probiert und das bekomme ich nicht hin. Ich habe es mit der Delphihilfe gemacht - die ist bei mir auf Englisch -, aber es gibt immer Fehler, wenn ich im Programm ein Item in der ComboBox markieren will, obwohl ich es genauso gemacht habe, wie es in der Hilfe steht.
Christian S. - So 08.12.02 22:06
Es wäre nicht schlecht, wenn Du Quelltext und Fehlermeldungen posten würdest, dann könnte ich (da Popov ja entschuldigt fehlt :wink: ) Dir evtl. helfen.
MfG,
Peter
Anonymous - So 08.12.02 22:41
Na, das kann ich doch nicht auf mir sitzen lassen:
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:
| implementation
{$R *.DFM}
const Liste = '0,1,2,3,4,5,6,7,8,9';
procedure TForm1.FormCreate(Sender: TObject); begin ComboBox1.Items.CommaText := Liste; ComboBox2.Items.CommaText := Liste; ComboBox3.Items.CommaText := Liste; end;
procedure TForm1.ComboBox1DropDown(Sender: TObject); begin with ComboBox1.Items do begin CommaText := Liste; with ComboBox2 do if IndexOf(Items[ItemIndex]) > -1 then Delete(IndexOf(Items[ItemIndex])); with ComboBox3 do if IndexOf(Items[ItemIndex]) > -1 then Delete(IndexOf(Items[ItemIndex])); end; end;
procedure TForm1.ComboBox2DropDown(Sender: TObject); begin with ComboBox2.Items do begin CommaText := Liste; with ComboBox1 do if IndexOf(Items[ItemIndex]) > -1 then Delete(IndexOf(Items[ItemIndex])); with ComboBox3 do if IndexOf(Items[ItemIndex]) > -1 then Delete(IndexOf(Items[ItemIndex])); end; end;
procedure TForm1.ComboBox3DropDown(Sender: TObject); begin with ComboBox3.Items do begin CommaText := Liste; with ComboBox1 do if IndexOf(Items[ItemIndex]) > -1 then Delete(IndexOf(Items[ItemIndex])); with ComboBox2 do if IndexOf(Items[ItemIndex]) > -1 then Delete(IndexOf(Items[ItemIndex])); end; end; |
Oder eine Kurzversion. Hier müssen allen ComboBox'en zusammen auf eine Prozedur zeigen:
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:
| implementation
{$R *.DFM}
const Liste = '0,1,2,3,4,5,6,7,8,9';
procedure TForm1.FormCreate(Sender: TObject); begin ComboBox1.Items.CommaText := Liste; ComboBox2.Items.CommaText := Liste; ComboBox3.Items.CommaText := Liste; end;
procedure TForm1.ComboBox_DropDown(Sender: TObject); begin if Sender is TComboBox then with TComboBox(Sender).Items do begin CommaText := Liste; with ComboBox1 do if IndexOf(Items[ItemIndex]) > -1 then Delete(IndexOf(Items[ItemIndex])); with ComboBox2 do if IndexOf(Items[ItemIndex]) > -1 then Delete(IndexOf(Items[ItemIndex])); with ComboBox3 do if IndexOf(Items[ItemIndex]) > -1 then Delete(IndexOf(Items[ItemIndex])); end; end; |
Anonymous - Mo 09.12.02 17:26
@ Popov: Deine Kurzfassung habe ich ausprobiert, aber sie funktioniert nicht richtig!
In der 1. ComboBox deren Eintrag ich ändere, werden danach nur noch
sechs Einträge angezeigt. Dies sind die Einträge, die in den beiden ComboBoxen bereits beim Start angewählt sind. Es wird jedoch nicht der
eigentlich ausgewählte Eintrag berücksichtigt.
In der 2. ComboBox deren Eintrag ich ändere, sind es dann
sieben Einträge (nur der letzte verbliebene Startwert fehlt).
Bei der 3. ComoBox deren Eintrag ich ändere, sind
acht Einträge vorhanden, weil es keinen "ürsprünglichen" Eintrag mehr gibt.
Ich wollte es aber so haben:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| 1. Walze 2. Walze 3. Walze
Walze Nr. I Walze Nr. VII Walze Nr. V
Walze Nr. II Walze Nr. II Walze Nr. II Walze Nr. III Walze Nr. III Walze Nr. III Walze Nr. IV Walze Nr. IV Walze Nr. IV Walze Nr. VI Walze Nr. VI Walze Nr. VI Walze Nr. VIII Walze Nr. VIII Walze Nr. VIII |
Wähle ich nun als 1. Walze eine andere Walze aus, so soll es so aussehen:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| 1. Walze 2. Walze 3. Walze
Walze Nr. III Walze Nr. VII Walze Nr. V
Walze Nr. I Walze Nr. I Walze Nr. I Walze Nr. II Walze Nr. II Walze Nr. II Walze Nr. IV Walze Nr. IV Walze Nr. IV Walze Nr. VI Walze Nr. VI Walze Nr. VI Walze Nr. VIII Walze Nr. VIII Walze Nr. VIII |
Das heisst, eine Veränderung in
einer der Walzen wirkt sich immer auf
alle drei Walzen aus.
Die Prozedurcode in die dein Quellcode reinmuss lautet im Moment so:
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:
| var AlleWalzenNummern : String = '"Walze Nr. I", "Walze Nr. II", "Walze Nr. III", "Walze Nr. IV", "Walze Nr. V", "Walze Nr. VI", "Walze Nr. VII", "Walze Nr. VIII"';
procedure TForm1.WalzenAuswahl(Sender: TObject); var i : Integer; begin AlleReflektoren := 'YRUHQSLDPXNGOKMIEBFZCWVJATFVPJIAOYEDRZXWGCTKUQSBNMHL'; AlleWalzen := ' EKMFLGDQVZNTOWYHXUSPAIBRCJAJDKSIRUXBLHWTMCQGZNPYFVOE BDFHJLCPRTXVZNYEIWGAKMUSQOESOVPZJAYQUIRHXLNFTGKDCMWB VZBRGITYUPSDNHLXAWMJQOFECKJPGVOUMFYQBENHZRDKASXLICTW NZJHGRCXMYSWBOUFAIVLPEKQDTFKQHTLXOCBJSPDZRAMEWNIUYGV';
if TComboBox(Sender).Name = 'AuswahlReflektor' then for i := 1 to 26 do Reflektor[i] := AlleReflektoren[i + 26 * AuswahlReflektor.ItemIndex];
if TComboBox(Sender).Name = 'AuswahlWalze1' then begin for i := 1 to 26 do Walze1[i] := AlleWalzen[i + 26 * AuswahlWalze1.ItemIndex]; end;
if TComboBox(Sender).Name = 'AuswahlWalze2' then begin for i := 1 to 26 do Walze2[i] := AlleWalzen[i + 26 * AuswahlWalze2.ItemIndex]; end;
if TComboBox(Sender).Name = 'AuswahlWalze3' then begin for i := 1 to 26 do Walze3[i] := AlleWalzen[i + 26 * AuswahlWalze3.ItemIndex]; end;
end; |
Anonymous - Mo 09.12.02 18:50
Hast du auch alle drei ComboBoxen auf die gleiche OnDropDown Prozedur (z.B. ComboBox1DropDown(Sender: TObject)) gelegt? Ohne das geht es nicht und die Ergebnisse sind falsch.
Eigentlich sind die Einzelversionen die richtige Lösung. Die Kurzversion hab ich auf die Schnelle hinzugefügt. Bei mir funktioniert sie wunderbar.
Anonymous - Mo 09.12.02 19:29
Ja, hab ich! :roll:
So blöd bin ich nun auch wieder nicht.
Wenn dann sollte es die Kurzversion sein, die ich wenden will, aber die funktioniert bei mir nicht. Ich kopiere sie aus deinem Posting und ändere nur ComboBoxX in AuswahlWalzeX und meine Prozedur heisst procedure TForm1.WalzenAuswahl(Sender: TObject), aber daran wirds ja wohl nicht liegen.
Es werden zwar die 3 ComoBoxen mit dem Inhalt Liste = '"Walze Nr. I", "Walze Nr. II", "Walze Nr. III", "Walze Nr. IV", "Walze Nr. V", "Walze Nr. VI", "Walze Nr. VII", "Walze Nr. VIII"'; gefüllt, aber wenn ich in einer ComboBox etwas auswähle, so passiert nichts. Auch wird das ausgewählte Item nicht als markiertes Item angeziegt, wenn ich geklickt habe.
Was mache ich falsch? :? *heul*
@ Peter: Vielleicht kannst du Popv das mal erklären, wie das bei mir laufen soll. Ich weiss nämlich nicht genau wie ichs erklären soll. :?
Christian S. - Mo 09.12.02 19:49
Zitat: |
Ja, hab ich!
So blöd bin ich nun auch wieder nicht. |
Dezenter Hinweis: Popov versucht Dir zu helfen.
Zitat: |
Vielleicht kannst du Popov das mal erklären, wie das bei mir laufen soll. Ich weiss nämlich nicht genau wie ichs erklären soll. |
Tja, soweit ich das überschaue, hat Popov das genau richtig verstanden. Wenn ich das bei mir versuche (Popovs kurze Lösung) funktioniert das perfekt. Wenn in jeder der ComboBoxen eine Walze ausgewählt ist, stehen bei jeder noch genau sechs zur Auswahl inklusive der aktuell getroffenen Auswahl. Stelbsversändlich stehen die Walzen, die in den jeweils anderen ComboBoxen ausgewählt sind, nicht mehr zur Verfügung. Meiner Meinung nach perfekt und schön kurz. Oder habe ich das Ganze auch falsch verstanden.
MfG,
Peter[/quote]
Anonymous - Mo 09.12.02 20:26
LOL!
Habe nochmal genau dasselbe mit der kurzen Lösung gemacht wie vorhin. Auf eine neue Form und nur drei ComboBoxen drauf. Und jetzt funktionierts, obwohl ichs vorhin genauso gemacht habe, und es da nicht geklappt hat. :?
Aber drei Fragen habe ich doch noch: :wink:
1. Geht das auch irgendwie mit csDropDownList? Einfach den Style ändern geht ja nicht. Ich will nämlich nicht, das eigene Einträge vorgenommen werden dürfen.
2. Wie kann ich die z.B. als 1. Walze ausgewählte Walze auch in den Einträgen der 1. Walze löschen, sodass pro Walze nur noch 5 Einträge nach der Auswahl vorhanden sind?
3. Wie kann ich es machen, dass auch eine Einstellung, die in Delphi festgelegt wurde, beim Start des Programms berücksichtigt wird? Denn wenn man das PRogramm startet, soll eine Voreinstellung da sein, die auch funktioniert.
Christian S. - Mo 09.12.02 20:58
zu 1.: tja, ändern kannst Du das schon, aber natürlich bekommst Du ein paar Probleme. Die sind aber nicht so gravierend, dass sie nicht lösbar wären. Da kannst Du mal ein bisschen selbst mit den verschiedenen Ereignissen einer ComboBox rumspielen.
zu 2.: Du speicherst ganz einfach, welches Item gerade ausgewählt ist, und löschst es auch noch in dem DropDown-Ereignis. Als Nutzer fände ich es allerdings sehr verwirrend, wenn dieses Item nicht mehr zur Verfügung stände. Ich würde es drin lassen.
zu 3.: wie oft haben wir jetzt schon mit ItemIndex gerarbeitet? :evil:
MfG,
Peter
Anonymous - Mo 09.12.02 21:11
@D0P3 F!$H
Wenn du mit csDropDownList arbeiten willst, du aber diesen Item nicht in der Liste haben willst, dann entziehst du dier ComboBox die Grundlage. ComboBox mit der Einstellung csDropDownList zeigt nicht den Text, sondern ein Itemwert. Ohne Item hast du auch kein Wert zum anzeigen.
Christian S. - Mo 09.12.02 21:40
Ich glaube, was er meint ist: das Item soll lediglich dann nicht auftauchen, wenn die Liste heruntergeklappt wird. Also nicht zur Auswahl zur Verfügung stehen, weil es im Grunde genommen ja schon ausgewählt ist. Wenn man kein anderes Item wählt, dann soll es wieder erscheinen,wenn die Liste eingeklappt wird. Er muss also das Item in den richtigen Ereignissen entfernen und wieder hinzufügen.
Anonymous - Mo 09.12.02 22:31
zu 1: Werd ich mal tun!
zu 2: Mal gucken wie ichs mache.
zu 3: :roll: Ist mir schon klar und es funktioniert auch eigentlich, aber die oberste ComboBox ist beim Starten des Programms gleich markiert und hat deshalb keinen Eintrag mehr. Das ist mein Problem!
zu den letzten beiden Posts: Also bisher hatte ich es so, dass ich in meinem Programm die 3 ComboBoxen auf Style := csDropDownList gestellt hatte, damit man keine eigenen Werte eintippen konnte. Mit diesen hätte das Proramm nämlich nicht mehr funktioniert.
@Popov: Ich verstehe nicht, was du meinst. Ich habe doch Werte in den ComboBoxen, die ich auswählen kann. Was meinst du mit deinem Post?
@Peter: Beziehst du dich damit auf zu 2, oder was? Was meinst du , wenn dem nicht so ist?
Christian S. - Mo 09.12.02 22:42
Zitat: |
@Peter: Beziehst du dich damit auf zu 2, oder was? Was meinst du , wenn dem nicht so ist? |
Ich habe versucht, Popov zu erklären, was Du meintest. Und ich hoffe, ich habe das richtig gemacht.
MfG,
Peter
Anonymous - Di 10.12.02 00:28
D0P3 F!$H hat folgendes geschrieben: |
@Popov: Ich verstehe nicht, was du meinst. Ich habe doch Werte in den ComboBoxen, die ich auswählen kann. Was meinst du mit deinem Post? |
Betrachte bitte die ComboBox. Die Eigenschaft Text kannst du nur bei csDropDown und csSimple nutzen. Text ist unabhängig von den Items, d.h. es muß keinen passenden Item zu dem Text geben. Bei csDropDownList ist das aber anders. Hier muß es zu dem angezeigtem Wert (es ist ja kein Text) einen Item-Wert geben. Wenn du also in der ComboBox1 nicht den Wert von ComboBox1 als Item haben willst, dann kannst du auch nicht den Wert in der Anzeige haben. Der angezeigte Wert ist der markierte Item und umgekehrt. Das ist eine Art Paradoxon. Ohne das Eine gibt es das Andere nicht. Und wenn du das immer noch nicht verstanden hast, dann lies dir das 10 mal durch und dann die Hilfe.
Natürlich kann man da mit Tricks arbeiten. Allerdings werde ich es nicht für dich machen.
Zu dem anderen Problem: du solltest dir langsam auch die Eigenschaften und Methoden von ComboBox durchlesen. Du muß ja nicht wegen jeder kleinsten Frage gleich hier posten. Zwar schreibst du das Programm alleine, fragst aber bei jeder Zeilen wie sie geschreiben werden soll. Wenn du dir das durchgelesen hättest, dann hättest du ItemIndex bemerkt. Dann einfach in der FormCreate ComboBox.ItemIndex := 0 eingeben und schon startet dein Programm mit dem ersten Eintrag.
Anonymous - Di 10.12.02 12:13
Zitat: |
Betrachte bitte die ComboBox. |
Was du da sagst verstehe ich nicht so ganz.
Was ich weiss ist, dass bei csSimple nur ein Eintrag möglich ist, den man selbst editieren kann.
Bei csDropDown gibt es vorgegebene Werte, allerdings kann man auch eigene Einträge angeben (Das darf bei mir nicht sein, weil ich in den ComboBoxen die Walzen auswähle und eigene Einträge nicht berücksichtigt werden können und deshalb das Prorgamm nicht funktionieren würde).
Bei csDropDownList gibt es nur vorgegebene Werte. Man kann keine eigenen Einträge hinzufügen.
Zitat: |
Zu dem anderen Problem: |
Kann ja sein, dass ich mich etwas umständlich ausgedrückt habe. aber wenn du wirklich glaubst, dass ich so blöde bin, dann tust du mir leid! Natürlich habe ich im ObjectInspector ItemIndex auf einen beliebigen Wert gesetzt, damit beim Progammstart eine Walzeneinstellung vorhanden ist.
Ich habe dein Programm ein bisschen umgestaltet:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| const Liste = '"Walze Nr. I", "Walze Nr. II", "Walze Nr. III", "Walze Nr. IV", "Walze Nr. V", "Walze Nr. VI", "Walze Nr. VII", "Walze Nr. VIII"';
implementation
{$R *.dfm}
procedure TForm1.WalzenDropDownListe(Sender: TObject); begin with TComboBox(Sender).Items do begin CommaText := Liste; with ComboBox1 do Delete(IndexOf(Items[ItemIndex])); with ComboBox2 do Delete(IndexOf(Items[ItemIndex])); with ComboBox3 do Delete(IndexOf(Items[ItemIndex])); end; end; |
Der Style ist auf csDropDownList und es gibt eine Voreinstellung. Es klappt soweit richtig, nur wenn ich einen Eintrag ändern will, so wird beim DropDown der ausgewähte Eintrag nicht angezeigt. Wenn ich beim DropDown keinen Eintrag asuwähle so wird leider keiner mehr angezeigt. Das sind die einzigen "Fehler".
Anonymous - Di 10.12.02 13:24
D0P3 F!$H hat folgendes geschrieben: |
... aber wenn du wirklich glaubst, dass ich so blöde bin, dann tust du mir leid! Natürlich habe ich im ObjectInspector ItemIndex auf einen beliebigen Wert gesetzt, damit beim Progammstart eine Walzeneinstellung vorhanden ist. |
Wo? Kann sein, daß es in der 6'er oder 7'er Version möglich ist im OI ItemIndex einzustellen. In der 3'er und 5'er kann man das nicht.
Zu deiner verkürzten Version:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm1.WalzenDropDownListe(Sender: TObject); begin with TComboBox(Sender).Items do begin CommaText := Liste; with ComboBox1 do Delete(IndexOf(Items[ItemIndex])); with ComboBox2 do Delete(IndexOf(Items[ItemIndex])); with ComboBox3 do Delete(IndexOf(Items[ItemIndex])); end; |
Natürlich kannst du dir die Sicherheitsabfrage hier sparen. Hier kann man davon ausgehen, daß eigentlich nichts passiert (solange alle CB's gleiche Liste haben und mehr als zwei Einträge). Allerdings kann es sonst passieren, daß IndexOf = -1 ist. In desem Fall bekommst du eine schöne Fehlermeldung. Bei meiner Version wird zuerst geprüft ob der Wert größer -1 ist. Mit Regeln ist es wie mit (keiner Ahnung mit was). Wenn man sich angewöhnt Sicherheitsabfragen im Code einzusetzen, dann kommt sowas später automatisch. Man denkt garnicht mehr drann und die Finger tippen solche Abfragen automatisch. Wenn man aber nur dann die Abfragen einbaut wenn man muß, dann muß man auch immer gut aufpassen.
IndexOf kann einen Fehler verursachen. Das könnte dein Lehrer auch bemerken und dich dannach fragen. Dann solltest du Ihm eine Antwort liefern können wieso es hier nicht zu Fehler kommen kann.
Christian S. - Di 10.12.02 15:39
Popov hat folgendes geschrieben: |
Wo? Kann sein, daß es in der 6'er oder 7'er Version möglich ist im OI ItemIndex einzustellen. In der 3'er und 5'er kann man das nicht. |
Ja, in meiner Version 6 ist das möglich. Allerdings wird bei Deinem Programm ja die Liste erst nach Programmstart geladen, dann klappt das natürlich nicht mehr.
Regeln: ich mache auch lieber ein paar Regeln zu viel als nur eine zu wenig. (Okay, wenn ich schnell was ausprobieren will in einem Programm, dass ich noch nicht mal speichern will, lasse ich die weg, aber ansonsten baue ich auch immer ziemlich (zu?) viele ein.
DOP3 F!$H hat folgendes geschrieben: |
Was du da sagst verstehe ich nicht so ganz. |
csDropDownList kann nur Einträge anzeigen, die auch in der Liste drin sind, die beim DropDown angezeigt wird. Es kann kein separates Label anzeigen. Also: wenn Du den Eintrag, der momentan angezeigt wird (weil er irgendwann vorher mal ausgewählt worden ist) nicht in der Liste haben willst, geht das nur dann, wenn er auch in dem Feld, welches die aktuelle Auswahl anzeigt, nicht mehr erscheinen soll.
DOP3 F!$H hat folgendes geschrieben: |
Es klappt soweit richtig, nur wenn ich einen Eintrag ändern will, so wird beim DropDown der ausgewähte Eintrag nicht angezeigt. Wenn ich beim DropDown keinen Eintrag asuwähle so wird leider keiner mehr angezeigt. |
Ich glaube nicht, dass man ersteres irgendwie ändern kann. Letzteres war das, von dem ich sagte, dass man es wahrscheinlich mit der richtigen Kombination von Ereignisbehandlungen lösen kann.
MfG,
Peter
Anonymous - Mi 11.12.02 21:17
Zitat: |
Wo? Kann sein, daß es in der 6'er oder 7'er Version möglich ist im OI ItemIndex einzustellen. In der 3'er und 5'er kann man das nicht. |
:oops: Sorry, wusste nicht, dass es auch Versionen gibt, bei denen das nicht geht!
Zitat: |
Das könnte dein Lehrer auch bemerken und dich dannach fragen. |
Könnte zwar sein, glaub ich aber eher nicht. Der konnte sich nicht genau vorstellen, wie ich denn die Enigma proggen wollte! :P
Zitat: |
Ich glaube nicht, dass man ersteres irgendwie ändern kann. |
In meinem Enigma-Prog hab ich das ComboBox-Ereignis OnChange benutzt und da funktioniert die Anzeige des momentan ausgewählten Wertes.
Ich habe allerdings bei meiner Enigma das Problem, dass ich bei Auswahl einer Walze diese ausgewählte Walze, die eigentlichen einen String darstellt, in die Variable Walze1 kopierern muss.
Nur wenn ich nun ein Item aus einen ComboBox lösche, so ändert sich ja auch die "Zahl", die das Item repräsentiert.
Beispiel:
In der ComoBox1 sind folgende Items aufgelistet:
Quelltext
1: 2: 3: 4: 5: 6:
| Walze Nr. I Walze Nr. II Walze Nr. III Walze Nr. V Walze Nr. VI Walze Nr. VIII |
I wird in ComboBox1 "verwendet", IV in ComboBox2 und VII in ComboBox3.
Wenn ich jetzt aber Walze Nr. VI auswählen will, so heisst das (wie es eigentlich funktionieren müsste), dass in ComboBox1 das Item "Walze Nr. I" durch "Walze Nr. VI" ersetzt wird. Zusätzlich wird dann aus
Quelltext
1: 2: 3: 4:
| AlleWalzen : String = 'EKMFLGDQVZNTOWYHXUSPAIBRCJAJDKSIRUXBLHWTMCQGZNPYFVOE BDFHJLCPRTXVZNYEIWGAKMUSQOESOVPZJAYQUIRHXLNFTGKDCMWB VZBRGITYUPSDNHLXAWMJQOFECKJPGVOUMFYQBENHZRDKASXLICTW NZJHGRCXMYSWBOUFAIVLPEKQDTFKQHTLXOCBJSPDZRAMEWNIUYGV' |
der passende Abschnitt für "Walze Nr. VI" gesucht wird. Dies geschieht durch
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| procedure TForm1.WalzenAuswahl(Sender: TObject); var i : Integer; begin AlleReflektoren := 'YRUHQSLDPXNGOKMIEBFZCWVJATFVPJIAOYEDRZXWGCTKUQSBNMHL'; AlleWalzen := 'EKMFLGDQVZNTOWYHXUSPAIBRCJAJDKSIRUXBLHWTMCQGZNPYFVOE BDFHJLCPRTXVZNYEIWGAKMUSQOESOVPZJAYQUIRHXLNFTGKDCMWB VZBRGITYUPSDNHLXAWMJQOFECKJPGVOUMFYQBENHZRDKASXLICTW NZJHGRCXMYSWBOUFAIVLPEKQDTFKQHTLXOCBJSPDZRAMEWNIUYGV';
if TComboBox(Sender).Name = 'AuswahlReflektor' then for i := 1 to 26 do Reflektor[i] := AlleReflektoren[i + 26 * AuswahlReflektor.ItemIndex];
if TComboBox(Sender).Name = 'AuswahlWalze1' then begin for i := 1 to 26 do Walze1[i] := AlleWalzen[i + 26 * AuswahlWalze1.ItemIndex]; end; if TComboBox(Sender).Name = 'AuswahlWalze2' then begin for i := 1 to 26 do Walze2[i] := AlleWalzen[i + 26 * AuswahlWalze2.ItemIndex]; end; if TComboBox(Sender).Name = 'AuswahlWalze3' then begin for i := 1 to 26 do Walze3[i] := AlleWalzen[i + 26 * AuswahlWalze3.ItemIndex]; end; end; |
Der eigentlich richtige Abschnitt zu Walze Nr. VI ist
JPGVOUMFYQBENHZRDKASXLICTW aber weil VI in ComboBox1 an 5. Position (ItemIndex = 4). Deshalb wird - durch meine Prozedur bedingt - für VI der Abschnitt
ESOVPZJAYQUIRHXLNFTGKDCMWB (was der Walze Nr. IV entspricht!) ausgesucht.
Daher weiss ich nicht, wie ich das ohne neue Variablen richtig hinkriegen kann.
Eigene Werte sind durch csDropDownList nicht möglich.
In meinem Programm funktioniert die anzeige des momentan ausgewählten Items bei DropDown und wenn ich nichts auswähle, so wird das zuletzt ausgewählte Item weiterbenutzt.
Könbnt ihr mir da helfen, wie ich (ihr) das gescheid hinkriegen kann (könnt)?
Hoffe, ihr seid noch mitgekommen, sonst einfach fragen!
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!