1 Son düzenleyen, ugurlu2001 (15.09.2015 13:13:21)

Konu: Form Class :: Form Class :: Object class is invalid for this container

Hali hazırda bir FORM tabanlı frmBase classım var.
Bu form class içerisinde  projede dahil olan tüm diğer formlarda kullanmak istediğim ortak özellikler bulunuyor.
Yani yapım kabaca şöyle :

frmBASE
frmliste::frmBase

Sorunun ise form tabanlı class ile çalışmakla ilgili olduğunu düşünüyorum.

frmListeye NEWOBJECT komutu ile bir CursorAdapter eklemek istediğimde başlıktaki hata mesajını alıyorum. "frmListe", class olarak tanımlı olduğu için; dataenvironment kısmına builder kullanarak bir ekleme yapamıyorum.

Sorularım ise şunlar:
* Class based bir formda cursor adapter ile çalışmak mümkü mü?
* Eğer sürekli class based form ile çalışmaya devam edersem sorun yaşarmıyım.

Yada en iyi yol; bir custom class oluşturup; her forma eklemek mi?

Yorumlar için şimdiden çok teşekkür ediyorum. Umarım kolay bir çözümü vardır.
Sevgiler...

Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır.  Türk Atasözü

2

Re: Form Class :: Form Class :: Object class is invalid for this container

DataEnvironment ayri bir object ve Form.DataEnvironment aslinda ona referans tutan bir property.

Class tabanli bir formda tabii ki CA kullanabilirsin, Dataenvironment'a ihtiyacin yok zaten. NewObject ile CA'ni yaratabilirsin ve onu bir property'e atarsin. Ornek:

Visual Fox Pro
Public oForm

oForm = Createobject('CaForm')
oForm.Show()
 
Define Class CaForm As Form
  ConnectionString = 'Provider=SQLNCLI;Trusted_connection=Yes;Server=.\SQLExpress;Database=Northwind'
  Add Object txtCountry As TextBox
  Add Object grdCustomers As Grid With RecordSource='Customers', Top=30
 
  Procedure Load
    This.AddProperty( 'oCustomer', Createobject('CaGeneric',This.ConnectionString) )
 
    With This.oCustomer
      .Alias          = 'customers'
      TEXT TO .SelectCmd  noshow
SELECT * FROM Customers WHERE Upper(country) = ?m.Country
      ENDTEXT
    Endwith
 
    Country = Null
    This.oCustomer.QueryFill()
    Select (This.oCustomer.Alias)
    This.oCustomer.MakeUpdatable('NorthWind..Customers','customerId')
  Endproc
 
  Procedure txtCountry.LostFocus
    Local Country
    Country = Upper(Trim(This.Value))
    Thisform.oCustomer.CursorRefresh()
  Endproc
Enddefine
 
Define Class CaGeneric As CursorAdapter
  CompareMemo = .F.
  FetchAsNeeded = .T.
  FetchSize = 100
  FetchMemo = .T.
  BatchUpdateCount = 100
  WhereType = 1
  AllowSimultaneousFetch = .T.
  MapVarchar = .T.
  MapBinary = .T.
  BufferModeOverride = 5
 
  DataSourceType = 'ADO'
  InsertCmdDataSourceType = 'ADO'
  UpdateCmdDataSourceType = 'ADO'
  DeleteCmdDataSourceType = 'ADO'
 
  Procedure Init(tcConnectionString)
    Set Multilocks On
    Local loConnDataSource
    loConnDataSource = Createobject('ADODB.Connection')
    loConnDataSource.ConnectionString = m.tcConnectionString
    loConnDataSource.Open()
    This.Datasource = Createobject('ADODB.RecordSet')
    This.Datasource.CursorLocation   = 3  && adUseClient
    This.Datasource.LockType         = 3  && adLockOptimistic
    This.Datasource.ActiveConnection = m.loConnDataSource
    loCommand = Createobject('ADODB.Command')
    loCommand.ActiveConnection = loConnDataSource
    This.AddProperty('oCommand',loCommand)
    Store loCommand To ;
      This.UpdateCmdDataSource,;
      This.InsertCmdDataSource,;
      This.DeleteCmdDataSource
  Endproc
 
  Procedure MakeUpdatable(tcTableName,tckeyField,tlDoNotIncludeKey)
    This.Tables = m.tcTableName
    This.KeyFieldList = m.tckeyField
    Local ix, lnUpdateableFCount
    lnUpdateableFCount = Fcount(This.Alias)-Iif(This.DataSourceType='ADO',1,0) && last one is ADOBOOKMARK
    For ix = 1 To m.lnUpdateableFCount
      If !m.tlDoNotIncludeKey Or !(Upper(Field(m.ix,This.Alias,0)) == Upper(m.tckeyField))
        This.UpdatableFieldList = This.UpdatableFieldList + ;
          IIF(Empty(This.UpdatableFieldList),'',',') + ;
          FIELD(m.ix,This.Alias,0)
      Endif
      This.UpdateNameList = This.UpdateNameList + ;
        IIF(Empty(This.UpdateNameList),'',',') + ;
        TEXTMERGE('<<FIELD(m.ix,this.Alias,0)>> <<m.tcTableName>>.<<FIELD(m.ix,this.Alias,0)>>')
    Endfor
  Endproc
 
  Procedure QueryFill()
    Local llSuccess
    If This.DataSourceType ="ADO"
      llSuccess = This.CursorFill(.F.,.F.,0,This.oCommand)
    Else
      llSuccess = This.CursorFill(.F.)
    Endif
    If !m.llSuccess
      If This.DataSourceType ="ADO"
        lcMessage = This.oCommand.CommandText + Chr(13) + This.GetErrorExplanation()
      Else
        lcMessage = This.GetErrorExplanation()
      Endif
      Messagebox(m.lcMessage)
    Endif
    Return m.llSuccess
  Endproc
 
  Procedure GetErrorExplanation
    Local lcError,ix
    Local Array aWhy[1]
    Aerror(aWhy)
    lcError = ""
    For ix = 1 To 7
      lcError = m.lcError + Transform(aWhy[m.ix]) + Chr(13)
    Endfor
    Return m.lcError
  Endproc
Enddefine

Not: Eger istersen bir vcx'ten normal scx form da yaratabilirsin:

create form frmListe as frmBase from classlibName.vcx

3 Son düzenleyen, ugurlu2001 (15.09.2015 18:26:33)

Re: Form Class :: Form Class :: Object class is invalid for this container

Üstat, yine hızır gibi yetiştin.

Aslında kutuda bekleyen bir soruya daha cevap verdin bu arada:

Visual Fox Pro
Create Form frmListe as frmBase From classlibName.vcx

Peki yukarıdaki kullanım şeklinde; frmBase yaptığım değişikler frmListe ye de ekleniyor mu?

Sağolasın. Allah Aklına, Sağlığına, Kalbine ve Ellerine dert göstermesin smile

Bu arada aşağıdaki kod örneğini ODBC ye uyarlayabilirmiyiz?   Malum, PostgreSQL de ADO desteği yok. DataSourceType = 'ADO' kısmını 'ODBC ye uyarlamakta biraz sorun yaşadım. Örnekte, MEMO field ve UTF8 field ( Aslında PostgreSQL database inde CodePage : 1254 )  özellikleri de olursa tadından yenmez. smile

Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır.  Türk Atasözü

4

Re: Form Class :: Form Class :: Object class is invalid for this container

Galiba bu link de günün sürpriz yumurtası oldu :

http://www.npgsql.org/

https://github.com/npgsql/npgsql

Versiyon 3.0.2 stable görünüyor.

Henüz incelemedim. Opensoruce olması büyük avantaj.

Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır.  Türk Atasözü

5

Re: Form Class :: Form Class :: Object class is invalid for this container

Üstat, Foxite de ODBC için yazdığın örneği buldum. Arşiv niteliğinde olsun diye buraya da post ediyorum ( izninle ) smile

Bu arada, aşağıdaki satır ile Class tan form yaratırsak; Inheritence ile tüm özelliklerini mi alıyor, yoksa Class ın o anki özellikleri ile yeni bir form mu oluşturuyor?

Visual Fox Pro
Create Form frmListe as frmBase From classlibName.vcx

http://www.foxite.com/archives/spt-in-class-0000217809.htm

Visual Fox Pro
Local loCursor, lcConStr

*!*    lcConStr = 'Driver={SQL Native Client};Trusted_connection=Yes;Server=.'
*!*    loCursor = Newobject('CaGeneric','cageneric.prg','','ODBC',m.lcConStr)
 
lcConStr = 'Provider=SQLNCLI;Trusted_connection=Yes;Server=.\SQLExpress'
loCursor = Newobject('CaGeneric','cageneric.prg','','ADO',m.lcConStr)
 
With loCursor
  .Alias          = 'myTable'
  TEXT TO .SelectCmd  noshow
SELECT * FROM NorthWind..Customers cus WHERE country = ?m.Country
  ENDTEXT
ENDWITH
 
Country = 'USA'
If loCursor.QueryFill()
  Select (loCursor.Alias)
 
  loCursor.MakeUpdatable('NorthWind..Customers','customerId')
  Browse Last
  Tableupdate(2,.T.,loCursor.Alias)
Endif
 
 
Country = 'UK'
If loCursor.QueryFill()
  Select (loCursor.Alias)
 
  loCursor.MakeUpdatable('NorthWind..Customers','customerId')
  Browse Last
  Tableupdate(2,.T.,loCursor.Alias)
Endif
 
 
Define Class CaGeneric As CursorAdapter
  CompareMemo = .F.
  FetchAsNeeded = .T.
  FetchSize = 100
  FetchMemo = .T.
  BatchUpdateCount = 100
  WhereType = 1
  AllowSimultaneousFetch = .T.
  MapVarchar = .T.
  MapBinary = .T.
  BufferModeOverride = 5
  *!*      *  Nodata = .T.
  Handle = 0
 
  Procedure AutoOpen
    If Not Pemstatus(This, '__VFPSetup', 5)
      This.AddProperty('__VFPSetup', 1)
      This.Init()
    Endif
  Endproc
 
  Procedure Init(tcType,tcConnectionString)
    Local llReturn
    Do Case
      Case Not Pemstatus(This, '__VFPSetup', 5)
        This.AddProperty('__VFPSetup', 0)
      Case This.__VFPSetup = 1
        This.__VFPSetup = 2
      Case This.__VFPSetup = 2
        This.__VFPSetup = 0
        Return
    Endcase
    Set Multilocks On
    llReturn = DoDefault()
 
    This.DataSourceType = m.tcType
 
    Store This.DataSourceType To ;
      this.InsertCmdDataSourceType, ;
      this.UpdateCmdDataSourceType, ;
      this.DeleteCmdDataSourceType
 
    ***<DataSource>
    Do Case
      Case Upper(This.DataSourceType) == "ODBC"
        This.Handle = Sqlstringconnect(m.tcConnectionString)
 
        Store This.Handle To ;
          This.Datasource,;
          This.InsertCmdDataSource,;
          This.UpdateCmdDataSource,;
          This.DeleteCmdDataSource
 
      Case Upper(This.DataSourceType) == "ADO"
        Local loConnDataSource
        loConnDataSource = Createobject('ADODB.Connection')
        ***<DataSource>
        loConnDataSource.ConnectionString = m.tcConnectionString
        ***</DataSource>
        loConnDataSource.Open()
        This.Datasource = Createobject('ADODB.RecordSet')
        This.Datasource.CursorLocation   = 3  && adUseClient
        This.Datasource.LockType         = 3  && adLockOptimistic
        This.Datasource.ActiveConnection = loConnDataSource
        *** End of Select connection code: DO NOT REMOVE
 
        loCommand = Createobject('ADODB.Command')
        loCommand.ActiveConnection = loConnDataSource
        This.AddProperty('oCommand',loCommand)
        This.UpdateCmdDataSource=loCommand
        This.InsertCmdDataSource=loCommand
        This.DeleteCmdDataSource=loCommand
 
      Case Upper(This.DataSourceType)="NATIVE" && Not implemented
      Case Upper(This.DataSourceType)="XML"  && Not implemented
    Endcase
    ***</DataSource>
 
    If This.__VFPSetup = 1
      This.__VFPSetup = 2
    Endif
    Return llReturn
  Endproc
 
  Procedure MakeUpdatable(tcTableName,tckeyField,tlDoNotIncludeKey)
    This.Tables = m.tcTableName
    This.KeyFieldList = m.tckeyField
    Local ix, lnUpdateableFCount
    lnUpdateableFCount = Fcount(This.Alias)-Iif(This.DataSourceType='ADO',1,0) && last one is ADOBOOKMARK
    For ix = 1 To m.lnUpdateableFCount
      If !m.tlDoNotIncludeKey Or !(Upper(Field(m.ix,This.Alias,0)) == Upper(m.tckeyField))
        This.UpdatableFieldList = This.UpdatableFieldList + ;
          IIF(Empty(This.UpdatableFieldList),'',',') + ;
          FIELD(m.ix,This.Alias,0)
      Endif
      This.UpdateNameList = This.UpdateNameList + ;
        IIF(Empty(This.UpdateNameList),'',',') + ;
        TEXTMERGE('<<FIELD(m.ix,this.Alias,0)>> <<m.tcTableName>>.<<FIELD(m.ix,this.Alias,0)>>')
    Endfor
  Endproc
 
  Procedure QueryFill()
    Local llSuccess
    If This.DataSourceType ="ADO"
      llSuccess = This.CursorFill(.F.,.F.,0,This.oCommand)
    Else
      llSuccess = This.CursorFill(.F.)
    Endif
    If !m.llSuccess
        If This.DataSourceType ="ADO"
            lcMessage = This.oCommand.CommandText + CHR(13) + This.GetErrorExplanation()
        ELSE
            lcMessage = This.GetErrorExplanation()
        endif   
      Messagebox(m.lcMessage)
    Endif
    Return m.llSuccess
  Endproc
 
  Procedure GetErrorExplanation
    Local lcError,ix
    Local Array aWhy[1]
    Aerror(aWhy)
    lcError = ""
    For ix = 1 To 7
      lcError = m.lcError + Transform(aWhy[m.ix]) + Chr(13)
    Endfor
    Return m.lcError
  Endproc
Enddefine
Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır.  Türk Atasözü