You are on page 1of 7

Aunque ya he comentado el contenido de esta entrada en el foro de facebook, necesitaba colgar de algún lado las fuentes que había

utilizado para revisar el tema y de paso, dar la oportunidad para quien todavía no forme parte del mismo pueda acceder a su contenido, o por lo menos a las cosas que parecen interesantes. Es por esa razón que he acabado añadiéndola. En este caso concreto, el hilo de comentarios del foro se originaba cuando uno de los compañeros, siguiendo las indicaciones del código publicado en el blog de Jim Tierney, que forma parte de los blogs de Embarcadero, se extrañaba de que al intentar llenar los items de un componente TListBox (en tiempo de ejecución) desde una fuente de datos (un clientdataset, el numero de items añadidos al TListBox era como máximo igual o menor a 200. Y eso sucedía aun cuando dicha fuente de datos contuviera una cantidad mayor.

Esta es la entrada en la que me he basado para reproducir el problema y comprenderlo. LiveBindings: Code to create TBindLink and fill a Listbox Creo que lo mas interesante de estas lineas no es ya la corrección que se ha hecho para solucionar el problema, que solo ha consistido en añadir la linea de asignación en el procedimiento FillList( ) de la unidad UMain.pas

BufferCount:= ARecordCount. ABufferCount: Integer). Para probarlo. cualquier movimiento hacia adelante de la estructura del enumerador.FDataLink. simplemente acceded a la propiedad LiveBindings del TListBox y cread un nuevo enlace de tipo TBindList. in buffer end. if ABufferCount > 0 then FBindScope. FSaveActiveRecord := FBindScope. // default to max 200 records Al final.BufferCount := 200.ActiveRecord. el valor del campo en cuestión es correcto. FNextRecord := FSaveActiveRecord. porque de hecho el comentario en la misma linea corrobora que se hizo por alguna razón que ahora mismo ciertamente no comprendo. comprobaba si habia llegado al ultimo registro por lo que aunque existiera una cantida mayor en el dataset. Lo mas gracioso de todo es que pienso que esto debería por la forma en que se ha planteado afectar en tiempo de diseño por lo que quizás deberíamos comprobar que al crear una relación TBindList desde el editor de expresiones. const AMemberName: string.Create(ABindScope: TCustomBindScopeDB.FDataLink.LBindList.FDataLink. begin FBindScope := ABindScope. FMemberName := AMemberName. En fin… cosas de los valores por defecto que supongo que sería fijado por algún motivo. ese era el motivo por el que. sino en destacar el punto que originaba el problema: constructor TBindScopeDBEnumerator. el enlace le indicaba que había llegado al último. Podéis hacer la prueba y comentamos en el foro. no estando definido el valor del campo BufferCount en TBindList. Y seguidamente definid para la propiedad Format un .BufferCount := ABufferCount else FBindScope. en tiempo de diseño.

En las pruebas que he hecho.Provider.DBScope. unit UMain. FMX.UITypes.DBEngExt. System. FMX.Layouts.EngExt. Data. FMX. también se reproduce el error.Classes.Types.Variants. FMX.ADODB. System.DBClient. Data.Bind.Editors.nuevo item con los valores indicados en la rutina FillList( ).Bind. System. FMX. interface uses System.Types.DB. Datasnap.Bind. Tened en cuenta este punto para no caer en el problema.Components.Controls. Fmx. Data.SysUtils. System.Dialogs. FMX.Bind.Forms. Data. Datasnap. . FMX.Bind.Win. Data.ListBox.

dsData: TDataSource. cdsDataCustNo: TFloatField. lbItemsCount: TLabel. var frmFillListBox: TfrmFillListBox. bnClear: TButton. procedure FillLabelItemsCount. dspData: TDataSetProvider. qData: TADOTable.fmx} . cdsData: TClientDataSet. Conexion: TADOConnection. cdsDataOrderNo: TFloatField. public { Public declarations } end. BindScopeDB1: TBindScopeDB. lbRecordCount: TLabel. procedure bnClearClick(Sender: TObject).type TfrmFillListBox = class(TForm) lbxData: TListBox. BindingsList1: TBindingsList. procedure FormCreate(Sender: TObject). implementation {$R *. bnFill: TButton. private { Private declarations } procedure FillLabelRecordCount. procedure bnFillClick(Sender: TObject).

LBindList. begin LBindList := TBindList.AddExpression do begin SourceExpression := ASourceExpression.embarcadero. end. const AControlExpression: string. LBindList. ASource: TBaseBindScopeComponent.BufferCount:= ARecordCount. siguiendo lo que haria el usuario en tiempo de diseño.Linea añadida with LBindList.Free.FormatExpressions.//fuente del procedimiento: http://blogs. LBindList.com/jimtierney // // // // // // procedure FillList(AControl: TComponent.ControlComponent := AControl. const ASourceMemberName: string = ''). LBindList.bnClearClick(Sender: TObject).AutoActivate := False.SourceComponent := ASource. LBindList.Create(nil).embarcadero. end. ControlExpression := AControlExpression. //<. LBindList. var LBindList: TBindList.SourceMemberName := ASourceMemberName.com/jimtierney/2011/10/03/31601 procedure TfrmFillListBox. Es util para el tiempo de ejecución http://blogs. const ASourceExpression: string. end. finally LBindList.AutoFill := False. try // Turn off auto properties. LBindList. . El procedimiento encapsula los pasos para rellenar distintos tipos de controles. ARecordCount: Integer.FillList.

OLEDB. procedure TfrmFillListBox.FormCreate(Sender: TObject). FillLabelItemsCount. 'Items.0.FillLabelRecordCount. .DataSet. 'OrderNo'. ). BindScopeDB1. 'AsString'.Count).'+ 'Data Source=C:Program FilesCommon FilesCodeGear SharedDatadbdemos.RecordCount). dsData.Text:= end.FillLabelItemsCount. FillLabelRecordCount. end.bnFillClick(Sender: TObject). FillLabelItemsCount. procedure TfrmFillListBox.'+ 'Persist Security Info=False'. 'Text'. begin Conexion. end.Items. cdsData.begin lbxData.4.Jet.Clear. FillLabelRecordCount. 'RecordCount: '+IntToStr(cdsData. begin lbItemsCount. FillLabelItemsCount.mdb.RecordCount.Count: '+IntToStr(lbxData. procedure TfrmFillListBox. begin FillList(lbxData.ConnectionString:= 'Provider=Microsoft. begin lbRecordCount. procedure TfrmFillListBox.Text:= end.Open.

Si deseáis ver el ejemplo podéis acceder al siguiente enlace: . end. Nada mas por comentar.FillLabelRecordCount. end.