Einzelnen Beitrag anzeigen

heri

Registriert seit: 20. Mär 2006
81 Beiträge
 
Delphi 2006 Enterprise
 
#1

Verbesserungsvorschlag: TcxDBTreeList with unbounded Fields

  Alt 30. Nov 2007, 16:47
Aufgabe 1:
Stellen Sie folgende 100 Datensätze einer TADOQuery in einem cxDBTreeList hierarchisch dar:

Field1; Name: Id Value: {1..100} //Identity
Field2; Name: ParentId Value: {1..100} //TreeNode ParentId
Field3; Name: Description Value: {Node1..Node100}

Kein Problem:
cxDBTreeList.Datasource := dsADOQuery1;
cxDBTreeList.KeyField := 'Id';
cxDBTreeList.ParentField := 'ParentId';
und erstelle die gewünschten Columns

Problem: Ungebundene Felder
Ergänzen Sie den Tree mit einer Spalte Checkbox (welche NICHT in der DB ist) um beliebige Werte zu aktivieren (und irgendwie später zu verarbeiten)

Mein Lösungsvorschlag zum Testen:
Platziere folgende Kompos auf deiner Form:
1 x TADOQuery (ADOQuery1)
1 x TClientDataset (ClientDataset1)
1 x TDatasource (dsClientDataset)
1 x TcxDBTreeList (cxDBTreeList1)

dsDatasource.dataset := ClientDataset1
cxDBTreeList1.Datasource := dsClientDataset

Ergänze cxDBTreeList1.Columns mit einer zusätzlichen Column (mit Properties Checkbox)

1 x TButton with Code:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
fField: TField;
fd: TFieldDef;
v: Array of TVarRec;
bCheckedDefaultValue: Variant;

  //kopiert hier irgendwo aus der DP - many thx to the coder!
  function CreateVariantPtr(_Value: variant): pVariant;
  begin

    GetMem( Result, SizeOf(Variant) );

    Initialize(Result^);

    Result^ := _Value;

  end;

begin

  //Copy FieldDefs from ADOQuery to ClientDataset
  for i := 0 to adoquery1.FieldDefList.Count - 1 do
  begin

    fd := ClientDataSet1.FieldDefs.AddFieldDef;

    fd.Name := adoquery1.FieldDefList.FieldDefs[i].Name;
    fd.DataType := adoquery1.FieldDefList.FieldDefs[i].DataType;
    fd.Precision := adoquery1.FieldDefList.FieldDefs[i].Precision;
    fd.Size := adoquery1.FieldDefList.FieldDefs[i].Size;

  end;

  //Add unbounded FieldDefs
  fd := ClientDataSet1.FieldDefs.AddFieldDef;
  fd.Name := 'Checked';
  fd.DataType := ftBoolean;
  fd.Precision := 0;
  fd.Size := 0;

  bCheckedDefaultValue := True;


  //Create DataSet
  ClientDataSet1.CreateDataSet;

  //Prepare Variant Record
  SetLength( v, ClientDataSet1.FieldDefs.Count );


  //copy Data from TADOQuery To TClientDataset
  adoQuery1.First;
  while NOT adoQuery1.Eof do
  begin

    for i := 0 to ClientDataSet1.FieldDefs.Count - 1 do
    begin

      v[i].VType := vtVariant;

      fField := adoQuery1.FindField( ClientDataSet1.FieldDefs[i].Name );

      if assigned(fField) then
         v[i].VVariant := CreateVariantPtr( fField.AsVariant )
      else
      if ClientDataSet1.FieldDefs[i].Name='Checkedthen
         v[i].VVariant := CreateVariantPtr( bCheckedDefaultValue )
      else


    end;

    ClientDataSet1.AppendRecord( v );

    adoQuery1.Next;

  end;

  //set cxDBTreeList

  cxDBTreeList1.DataController.KeyField := 'NodeId';
  cxDBTreeList1.DataController.ParentField := 'ParentId';

  cxDBTreeList1.Columns[0].DataBinding.FieldName := 'Checked';
  cxDBTreeList1.Columns[1].DataBinding.FieldName := 'NodeId';
  cxDBTreeList1.Columns[2].DataBinding.FieldName := 'ParentId';
  cxDBTreeList1.Columns[3].DataBinding.FieldName := 'Bezeichnung';

end;

Nun, so ist mein Ansatz - der auch funktioniert!
Vielleicht hat aber jemand Lust den Code zu perfektionieren und in die CodeLib zu beantragen

Viel Spass und ich hoffe falls jemand mal das gleiche Problem zu lösen hat - er habe hier einen Ansatz gefunden[b]
  Mit Zitat antworten Zitat