Konu: Enable/disable
yapmış olduğum formlardaki get alanlarını bir tuşa bağlı olarak (edit yada add) enable yada disable olmasını istiyorum. aynı şeyı cmdbuttonlar içinde geçerli bu işi en kolay nasıl yaparım.
Giriş yapmadınız. Lütfen giriş yapın yada kayıt olun.
yapmış olduğum formlardaki get alanlarını bir tuşa bağlı olarak (edit yada add) enable yada disable olmasını istiyorum. aynı şeyı cmdbuttonlar içinde geçerli bu işi en kolay nasıl yaparım.
eğer bir butondaysan:
thisform.mybutton.enabled=.t.
eğer formun methotlarındaysan:
this.mybutton.enabled=.t.
da olur.
Get alanları derken herhalde TextBox anlamına geliyor.
Bunun için farklı yöntemler var aslında. En kolayı tüm bu alanları bir container içine al ve bir tuş ile
Container.Enabled = .F. ve .T. yapabilrsin.
Diğer bir yöntem ise
Kapa Button'un Click event'inde
LOCAL lText
FOR EACH lText IN thisform.Controls
IF LOWER(lText.Class) = "textbox"
lText.Enabled = .F.
ENDIF
ENDFOR
Aç Button'un Click event'inde
LOCAL lText
FOR EACH lText IN thisform.Controls
IF LOWER(lText.Class) = "textbox"
lText.Enabled = .T.
ENDIF
ENDFOR
SetAll komutunu incele
SetAll komutunu incele
cetinbasoz hocada aynı komutu söyledi ve en bu komtu beğendim. taki şu soru gelene kadar
Bir formun içindeki txtboxların fontunu nasıl bold yaparsın. setall() tam cevap değil sebebde şu :
cetinbasoz:
Bir form icinde bir suru "container" tipi kontrol bulundurabilir. Mesela pageframe. O zaman tum textboxlari secme sansin yok.SetAll()'da olmaz. Cunku SetAll()'un 3.parametresini ya kullanacaksin ya da kullanmayacaksin.
Kullanirsan: TextBox baseclassindan gelenler olur. Ama classinin adi "benimGuzelTextBoxim" ise olmaz (onun da basecalssi textox olmasina ragmen).
Kullanmazsan: Sadece textler degil fontbold yapma sansi olan her kontrol bold olur.
peki ozaman nasl yapılbilir ?
Recursive bir yapı ile tüm container ve pageframe içindeki textboxları kapama imkanın var ben sorunu herhalde tam olarak anlayamadım ama istersen aşağıdaki kodu bir dene
Procedure TextBoxKapa
LPARAMETERS aContainer
LOCAL lText, lPage
FOR EACH lText IN aContainer.Controls
DO CASE
CASE LOWER(lText.Class) = "textbox"
ltext.Enabled = .F.
CASE LOWER(lText.Class) = "pageframe"
FOR EACH lPage as Page IN lText.Pages
=TextBoxKapa(lPage)
ENDFOR
ENDCASE
ENDFOR
Soruyu ben sorayim:
Bir formdaki tum textboxlarin listesini nasil alirsin.
Ya da biraz daha zorlastirirsak:
Bir formdaki tum objelerin listesini nasil alirsin. Yani bir obje icerme sansi olan herseyi ve onun icindekileri.
Recursive cozumu var ancak resursion limitli.
Soruyu ben sorayim:
Bir formdaki tum textboxlarin listesini nasil alirsin.
Ya da biraz daha zorlastirirsak:
Bir formdaki tum objelerin listesini nasil alirsin. Yani bir obje icerme sansi olan herseyi ve onun icindekileri.
Recursive cozumu var ancak resursion limitli.
Teşekkürler adaş, ama yanılmıyorsam eski versiyonlarda recursion 128 ile sınırlıydı. bir form üzerinde içinde obje içeren kaç tane container olabilir. Böyle bir yapı biraz kullanışsız ve kontrolü zor olmazmı.
=TextBoxListele(oForm)
Procedure TextBoxListele
LPARAMETERS aContainer
LOCAL lText, lPage
FOR EACH lText IN aContainer.Controls
DO CASE
CASE LOWER(lText.Class) = "textbox"
?lText.Class
CASE LOWER(lText.Class) = "pageframe"
FOR EACH lPage as Page IN lText.Pages
=TextBoxKapa(lPage)
ENDFOR
ENDCASE
ENDFOR
Kullanisli olan 4-5 seviyeli formlar var. Mesela form.pageframe.page.grid.column.textbox, ya da form.pageframe.page.grid.column.conatiner.textbox vs.
Aradigimiz obje textbox degil de, her ne olursa olsun deseydik, isin icine collection classlar bile giriyor. Ya da icice N tane custom. O zaman controls ile bu is olmuyor, pageframe ise pages, grid icin columns, comandgroup icin buttons vs collectionlari ayri ayri hesaba katmak gerekiyor. Bugun var olmayan "container" tipi bir kontrol bir sonraki versiyonda eklenebilir (ornegin collection VFP6da yok,VFP9 da var), ayni kod onu da isleyebilmeli. Yani once bir kontrol baska kontrolleri iceren bir "container" mi sorusuna cevap verebilen bir kod lazim. Pages, Buttons vs kullanmamasi gerekiyor sonucta.
Benim kod VFP5'ten beri yapiyor bu isi ve degismesi gerekmedi. Hemen kodu vermedim ve eksersiz olsun diye sormustum:)
Not: FoxyClasses kullanicilarinin hazir elinde var.
Hocam son yazdığın için aklıma çok fazla bir fikir gelmiyor açıkcası, FoxyClasses kullananlarda olduğuna göre onlarda bir sorun yok ancak ben FoxyClasses kullanmıyorum kendi class'larım var ve program içinde kullanacağım tüm objeleri muhakkak kendi classlarımı oluşturarak kullanıyorum. (TextBox, CheckBox, Pages, Container vs.) Bu tür durumlarda Class'ın bir tek yerinde bir methodla o objenin içinde başka objelerin olup olmadığını anlayabilirim.
Herbir class'a Property olarak HasChild ve Method olarak GetChild ekleyip listelemem veya özelliklerini değiştirmem mümkün.
diğer çözümleri artık sizden bekliyoruz, en azından bir ipucu fena olmazdı.
*class::FillCollection metodu
Lparameters oContainerObject
Local ix, nMembers, lnExpand, oObjectRef, aContainerObjects[1]
nMembers = amembers(aContainerObjects, oContainerObject,2)
With this
For ix = 1 to nMembers && Start collecting
lnExpand = iif(type(".aCollection[1]")= "L",0,1)
Dimension .aCollection[alen(.aCollection,1)+m.lnExpand]
oObjectRef = eval("oContainerObject."+aContainerObjects[m.ix])
.aCollection[alen(.aCollection,1)] = oObjectRef
* .aCollection[alen(.aCollection,1)] = Stuff(Sys(1272, oObjectRef),1,Len(Trim(thisform.name)),'thisform')
IF LOWER(oObjectRef.BaseClass) # "olecontrol" ;
AND LOWER(oObjectRef.BaseClass) # "oleboundcontrol"
.FillCollection(oObjectRef) && Recurse
endif
Endfor
Endwith
* Handle _screen and _vfp to also collect their objects
Do case
Case compobj(oContainerObject,_screen) && Handle _screen specially
For each oForm in _screen.Forms
This.FillCollection(oForm) && Recurse
Endfor
Case compobj(oContainerObject,_vfp) && Handle _vfp specially
For each oFrmObject in _vfp.Objects
This.FillCollection(oFrmObject) && Recurse
Endfor
* _screen.forms # _vfp.objects
* So also handle _screen.forms too
This.FillCollection(_screen)
Endcase
Yalniz dikkat et burada object referanslar toplanip bir arrayde saklaniyor. Bu durum "hanging object reference" nedeni olabilecegi icin bu metodu kullanan o sirada cagirip hemen referanlari birakmali:
thisform.oCollector.FillCollection( thisform )
* ne yapacaksa referanslarla ...
thisform.oCollector.ResetCollection() && class'in referanslari temizleyen kodu
Hocam code için teşekkürler.
hepiniz sağolun benim için bu kodlar oldukça ağır ama yavaş yavaş deneyerek bişeyler bulmaya çalışiyorum