none
Button in Collumns (andere Reihe, andere Farbe)

    Frage

  • Einen wunder schönen guten Tag liebe Comunity (oder Olaf, weil du bestimmt eh der einzige bist der antwortet XD XD)

    Mein Problem ist wie folgt. Ich habe ein grid mit n rows n columns. In jeder Column sind jeweils 3 Buttons. Der 1. Botton hat eine Rote farbe (backcolor), der zweite eine gelbe und der dritte eine grüne.

    jetzt will ich die mit DynamicCurrentControll so ändern, das der button in row 1 rot ist und in row2 grün (z.b).. aber wenn ich in in dem click ereignis von button 1 (b1) hineinschreibe [thisform.grid1.collumn1.dynamiccurrentcontrole = "b2" ] dann kommt die fehlermeldung, das der Ausdruck ungültig ist.

    anmerkung: das selbe bei currentcontroll funktioniert, nur das die komplette spalte geändert wird, und genau das soll ja nicht passieren..

    in der Hilfe steht nur, dass man mit dynamiccurentcontroll das objekt in einzelnen reihen ändern kann, aber es wird nicht beschrieben wie..

    Unterstüzung, oder vielleicht ne kleine anleitung wäre nett ^^

    ps.: ein anderer lösungsansatz wird auch akzeptier ;)


    • Bearbeitet Schosch93 Mittwoch, 12. Dezember 2012 12:53
    Mittwoch, 12. Dezember 2012 12:53

Antworten

  • DynamicCurrentControl soll ein Ausdruck sein, der einen Objektnamen des controls liefert. "b2" geht prinzipiell, wenn der button b2 heißt, aber nur, wenn b2 auch der Column zugefügt ist. Und das ist nicht das einzige, was du noch falsch verstanden hast:

    DynamicCurrentControl ist nicht eine Eigenschaft pro Zeile, sondern gilt für die gesamte Column. Um in jeder Zeile dynamisch unterschiedliche Controlnamen zurückzugeben, muß Dein Ausdruckz.B. je nach Recno() oder sonst einem Feldwert der angebundenen Tabelle unterschiedliche Objektnamen zurückgeben, sonst hat DynamicCurrentControl den absolut selben Effekt wie CurrentContol.

    Mach z.B. sowas: DynamicCurrentControl = "(ICASE(Recno()=1,'b1',Recno()=2,'b2','b3')"

    Damit das geht müssen die drei buttons nicht nur irgendwie im Formular liegen, sondern der jeweiligen Column zugefügt sein, per Code z.B. mittels grid.columnX.addobject("b1","commandbutton").

    Wie Du das visuell im Designer machst, ist eine kleine Wissenschaft für sich. Header anclicken, dann Control per drag&drop in die Column ziehen. So oder ähnlich. Ohne das ist "b1", "b2" etc. ein ungültiger Ausdruck, das ist richtig.

    Tschüß, Olaf.



    • Bearbeitet Olaf Doschke Donnerstag, 20. Dezember 2012 06:50
    • Als Antwort markiert Schosch93 Mittwoch, 30. Januar 2013 14:24
    Dienstag, 18. Dezember 2012 08:38

Alle Antworten

  • Hi,

    Du solltest Dir mal die SetAll Methode des Grids bzw. der Columns ansehen. Da kannst Du sämtliche Dynamic Eigenschaften gezielt umsetzen.

    DynamicCurrentControl kommt eigentlich dann zum Einsatz, wenn Du bspw. unterschiedliche Bilder oder Wechsel zwischen unterschiedlichen Funktionalitäten ermöglichen möchtest. Bei einem simplen ändern der Hintergrundfarbe ist das IMHO nicht notwendig.

    In der Hilfe sind übrigens ein paar Beispiele zu SetAll zu finden. Allerdings wird es bei etwas komplexeren Bedingungen schnell unübersichtlich. In einem solchen Fall steht es Dir aber frei, anstatt einer in Anführungszeichen hinterlegten IIF/ICASE Konstruktion einfach einen Funktionsaufruf zu hinterlegen, der dann den jeweiligen Wert zurückliefert. Dies funktioniert auch bei größeren Datenmengen recht zügig.

    Hier ein Beispiel aus der Hilfe in dem alternierende Hintergrundfarben für die Gridzeilen definiert werden:

    frmMyForm.grdGrid1.SetAll("DynamicBackColor", "IIF(MOD(RECNO( ), 2)=0, RGB(255,255,255), RGB(0,255,0))", "Column")
    

    Möchtest Du bspw. verschiedene Grafiken in einer Spalte anzeigen (analog zu verschiedenen CommandButtons) sähe das dann so aus:

    * // myValue steht für das Flag welches steuert, welche Grafik aktiviert sein soll
    Thisform.myGrid.grcMyColumn.DynamicCurrentControl	= [ThisForm.SetControl(myValue)]
    
    * // Das hier steht dann bspw. in der Methode Thisform.SetControl
    
    LPARAMETERS paValue
    PRIVATE lcReturn
    
    DO CASE 
    CASE ALLTRIM(paValue) == [1]
    	lcReturn = [img1]
    CASE ALLTRIM(paValue) == [1.1]
    	lcReturn = [img11]
    CASE ALLTRIM(paValue) == [1.2]
    	lcReturn = [img12]
    CASE ALLTRIM(paValue) == [1.3]
    	lcReturn = [img13]
    OTHERWISE 
    	lcReturn = []
    ENDCASE 
    
    RETURN lcReturn
    Das obige Beispiel funktioniert nur dann, wenn in der entsprechenden Column auch tatsächlich image-Objekte mit den definierten Namen enthalten sind ( -> img1, img11, img12, img13 ). Das Beispiel arbeitet auf Basis eines übergebenen String, aber Integerwerte sind ebenfalls möglich. Dann muss halt die Abfrage im CASE-Verteiler entsprechend modifiziert werden...


    Gruss / Best regards
    -Tom
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible,
    you are, by definition, not smart enough to debug it. 010101100100011001010000011110000101001001101111011000110110101101110011


    • Bearbeitet Tom Borgmann Donnerstag, 13. Dezember 2012 09:37 IMHO verlinked
    Mittwoch, 12. Dezember 2012 15:14
  • Also erstmal, was ist das IMHO und es sollen ja buttons sein, deren hintergrundfarbe geändert werden soll, wenn bestimmte bedingungen herschen.. es geht darum, dass ich an einer anderen stelle 3 stati definiert habe, und je nachdem, welcher status zutriff soll die farbe des buttons angepasst werden.

    Das hat doch nichts mit IMGs zu tun^^ Ich will einfach nur dass sich die Farbe eines Buttons ändert, ohne dass sich direckt die Farben aller Buttons in einer Collumn ändern.. quasi [x,y]: [1,1] = rot ; [1,2] = grün; [1,3] = rot; [1,4] = gelb... ect

    ich weiß dass es möglich ist unterschiedliche objecte in einer collumn anzeigen zu lassen, aber ich weiß halt nicht wie und das wird auch nicht in der hilfe beschrieben, nur das ein Ausdruck verlangt wird.. wie dieser ausdruck (zum beispiel anhand eines beispiels) aussehen soll steht da aber nicht..

    Und um das ganze erstmal zu verständniszwäcken zu testen wollte ich erstmal eine Farbänderung, wenn man auf den button klickt..

    • Bearbeitet Schosch93 Donnerstag, 13. Dezember 2012 07:18
    Donnerstag, 13. Dezember 2012 07:14
  • Das Deine Frage nichts mit images zu tun hat habe selbst ich verstanden.;-)

    Ich habe Dir oben eine Anleitung gegeben die Du an Deine Bedürfnisse anpassen kannst. Es ist egal ob Du in einer Column IMGs oder CMDs rumliegen hast. Die Funktionalität ist immer die gleiche, nur die Objektnamen werden sich entsprechend Deiner Vorlieben ändern.

    Dass Du an anderer Stelle drei Flags mitführst die den Farbstatus des jeweiligen Buttons steuern sollen ist prima, aber auch notwendig damit alles funktioniert.

    Das Umschalten zwischen den Objekten beschreibe ich Dir (wenn auch dummerweise mit imgs....Asche auf mein Haupt) im unteren Codeblock und wie bereits geschrieben: Passe ihn einfach an Deine Buttons an.

    p.s.

    Wieso images! Ich finde verschiedenfarbige Buttons einfach unästhetisch/unpraktisch/schlecht zu merken und setze es lieber in verschiedenen Grafiken um. Ein Bild sagt mehr als tausend Worte und noch mehr als viele Farben ;-)

    Und falls Du jetzt sagst: Ja, aber ein Button kann man anklicken! .... Das kann man ein Image auch :)))


    Gruss / Best regards
    -Tom
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible,
    you are, by definition, not smart enough to debug it. 010101100100011001010000011110000101001001101111011000110110101101110011

    Donnerstag, 13. Dezember 2012 09:48
  • Beim Button sieht das anklicken einfach cooler aus :D :D :D Wenn ich ein programm schreibe, dann mus alles so aussehn, wie ich das will. Und wenn ich mir dafür jedes einzelne Objekt mit shapes nachbauen muss.. da bin ich mega agresiv.. und wenn die verfügbaren objekte schon dem entsprechen, was ich mir vorstelle, dann kann ich die doch auch benutzen :D :D :D egal, geschmacksache ^^

    Aber ich versteh dein beispiel noch nicht so ganz, Ich habe im Moment nur die Fälle 1.Button ist rot.. 2.Button ist gelb und 3. button ist grün... und jeh nach dem welche farbe der button hat soll halt auf butten.click die farbe auf die nächste farbe gewechselt werden (immer im Kreis)..

    Außerdem fällt es mir schwer deinen bsp code umzumodelieren. Ich habe ja schon mit dem Asdruck [ThisForm.SetControl(myValue)]

    so meine problem.. Was sollte denn in myValue stehn ?  - einfach nur das jeweilige objekt (mit thisform.mygrid.column.object beschrieben) oder was?

    was hat es mit paValue auf sich?? und was steht in lcReturn??

    ps.: ich kann immer nur wiederholen, ich bin anfänger, desswegen bitte ich um nachsicht^^

    • Bearbeitet Schosch93 Donnerstag, 13. Dezember 2012 10:40
    Donnerstag, 13. Dezember 2012 10:04
  • IMHO : guggst Du hier:

    http://de.wikipedia.org/wiki/IMHO#I

    und wenn Du collumn's oder Botton's schreibst kannst Du tricksen wie Du willst,
    dann wird der Compiler mega-agresso und nix geht mehr :-))

    hth

    Horst

    Freitag, 14. Dezember 2012 19:08
  • DynamicCurrentControl soll ein Ausdruck sein, der einen Objektnamen des controls liefert. "b2" geht prinzipiell, wenn der button b2 heißt, aber nur, wenn b2 auch der Column zugefügt ist. Und das ist nicht das einzige, was du noch falsch verstanden hast:

    DynamicCurrentControl ist nicht eine Eigenschaft pro Zeile, sondern gilt für die gesamte Column. Um in jeder Zeile dynamisch unterschiedliche Controlnamen zurückzugeben, muß Dein Ausdruckz.B. je nach Recno() oder sonst einem Feldwert der angebundenen Tabelle unterschiedliche Objektnamen zurückgeben, sonst hat DynamicCurrentControl den absolut selben Effekt wie CurrentContol.

    Mach z.B. sowas: DynamicCurrentControl = "(ICASE(Recno()=1,'b1',Recno()=2,'b2','b3')"

    Damit das geht müssen die drei buttons nicht nur irgendwie im Formular liegen, sondern der jeweiligen Column zugefügt sein, per Code z.B. mittels grid.columnX.addobject("b1","commandbutton").

    Wie Du das visuell im Designer machst, ist eine kleine Wissenschaft für sich. Header anclicken, dann Control per drag&drop in die Column ziehen. So oder ähnlich. Ohne das ist "b1", "b2" etc. ein ungültiger Ausdruck, das ist richtig.

    Tschüß, Olaf.



    • Bearbeitet Olaf Doschke Donnerstag, 20. Dezember 2012 06:50
    • Als Antwort markiert Schosch93 Mittwoch, 30. Januar 2013 14:24
    Dienstag, 18. Dezember 2012 08:38
  • Vielleicht hilft Dir der folgende Code weiter...

    DEFINE CLASS grddemo AS form
    
    	DoCreate = .T.
    	Caption = "Form1"
    	Name = "Form1"
    
    	ADD OBJECT grid1 AS grid WITH ;
    		ColumnCount = 2, ;
    		DeleteMark = .F., ;
    		Height = 200, ;
    		Left = 25, ;
    		Top = 25, ;
    		Width = 320, ;
    		Name = "Grid1", ;
    		Column1.Sparse = .F., ;
    		Column1.Name = "Column1", ;
    		Column2.ControlSource = "fld_text", ;
    		Column2.Name = "Column2"
    
    	ADD OBJECT grddemo.grid1.column1.header1 AS header WITH ;
    		Caption = "Header1", ;
    		Name = "Header1"
    
    	ADD OBJECT grddemo.grid1.column1.command1 AS commandbutton WITH ;
    		Top = 29, ;
    		Left = 19, ;
    		Height = 27, ;
    		Width = 84, ;
    		Caption = "Grün", ;
    		BackColor = RGB(128,255,128), ;
    		Name = "Command1"
    
    	ADD OBJECT grddemo.grid1.column1.command2 AS commandbutton WITH ;
    		Top = 24, ;
    		Left = 29, ;
    		Height = 27, ;
    		Width = 84, ;
    		Caption = "Gelb", ;
    		BackColor = RGB(255,255,170), ;
    		Name = "Command2"
    
    	ADD OBJECT grddemo.grid1.column1.command3 AS commandbutton WITH ;
    		Top = 24, ;
    		Left = 44, ;
    		Height = 27, ;
    		Width = 84, ;
    		Caption = "Rot", ;
    		BackColor = RGB(255,202,202), ;
    		Name = "Command3"
    
    	ADD OBJECT grddemo.grid1.column2.header1 AS header WITH ;
    		Caption = "Header1", ;
    		Name = "Header1"
    
    	ADD OBJECT grddemo.grid1.column2.text1 AS textbox WITH ;
    		BorderStyle = 0, ;
    		Margin = 0, ;
    		ForeColor = RGB(0,0,0), ;
    		BackColor = RGB(255,255,255), ;
    		Name = "Text1"
    
    	PROCEDURE setcontrol
    		LPARAMETERS vValue as Integer
    		DO CASE 
    		CASE vValue = 1
    			RETURN [Command1]
    		CASE vValue = 2
    			RETURN [Command2]
    		CASE vValue = 3
    			RETURN [Command3]
    		ENDCASE 
    		RETURN []
    	ENDPROC
    
    	PROCEDURE Unload
    		USE IN SELECT([crsTest])
    	ENDPROC
    
    	PROCEDURE Init
    		Thisform.Grid1.Column1.DynamicCurrentControl=[ThisForm.SetControl(fld_buttonstatus)]
    	ENDPROC
    
    	PROCEDURE Load
    		CREATE CURSOR crsTest( fld_buttonstatus i, fld_text c(10) )
    		INSERT INTO crsTest (fld_buttonstatus, fld_text) VALUES ( 1 , [Grün] )
    		INSERT INTO crsTest (fld_buttonstatus, fld_text) VALUES ( 2 , [Gelb] )
    		INSERT INTO crsTest (fld_buttonstatus, fld_text) VALUES ( 3 , [Rot] )
    
    		GO TOP IN crsTest
    	ENDPROC
    
    ENDDEFINE
    

    Wenn Du Dir in einer normalen Form ein Grid zum Testen nachbaust, dann sollte es Dir beim Ausführen so etwas zeigen:

    Basis ist der im LOAD-Event der Form generierte Cursor und dessen 1. Spalte deren Wert für die korrekte Button-Selektion herangezogen wird.

    Relevant hierfür sind zum einen die korrekte Zuweisung der Cursor-Spalten an die Grid-Column, die INIT Methode mit der Definition des DynamicCurrentControl sowie die Form-Methode SetControl.

    Und nicht vergessen: Die Spalte mit den 3 Buttons mus auf Sparse=.F. gesetzt sein. Aber das kannst Du im Code genau nachlesen.


    Gruss / Best regards
    -Tom
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible,
    you are, by definition, not smart enough to debug it. 010101100100011001010000011110000101001001101111011000110110101101110011

    Dienstag, 18. Dezember 2012 09:30