Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.02.26;
Скачать: CL | DM;

Вниз

Описание структуры   Найти похожие ветки 

 
webpauk   (2006-02-06 15:33) [0]

Господа! Помогите объявить структуру следующего типа:
Item1
  Item1.1
  Item1.2
      Item1.2.1
      Item1.2.2
             Item1.2.2.1
             ...
  Item1.3  
  ...
глубина вложенности структур неизвестна.


 
Digitman ©   (2006-02-06 15:40) [1]

Что значит "объявить" ?


 
webpauk   (2006-02-06 15:43) [2]

Type
...


 
Desdechado ©   (2006-02-06 15:43) [3]

TTreeView


 
webpauk   (2006-02-06 15:45) [4]

Круто!
вот TtreeView я пытаюсь правильно отрисовать из базы, которая не сортирована по ID и IDPartner


 
webpauk   (2006-02-06 15:46) [5]


> Desdechado ©   (06.02.06 15:43) [3]
> TTreeView

вот TtreeView то я и пытаюсь правильно нарисовать


 
Digitman ©   (2006-02-06 15:49) [6]


> вот TtreeView то я и пытаюсь правильно нарисовать


Вот рассказывай, что у тебя неправильно получается ..

А "объявление структуры" здесь ни при чем - речь идет о заполнении TreeView в ран-тайм


 
Digitman ©   (2006-02-06 15:51) [7]


> которая не сортирована по ID и IDPartner


Что же мешает отсортировать ?


 
webpauk   (2006-02-06 15:55) [8]


> Digitman ©  

Caption      ID      IDParent
Все           1        0
Тип1         2        3
Тип2         3        1
Тип3         4        3

классический метод отрисовки дерева неправильно отображает представленную таблицу

procedure MakeTree;
var
  I, N: Integer;
begin
  with Form1 do
  begin
  TreeView1.Items.Clear;
  T1.First;
  for I := 1 to T1.RecordCount do
  begin
     if T1["IDParent"]=0 then DrawTree(nil)
     else
     begin
        for N := 0 to TreeView1.Items.Count-1 do
        begin
           if Integer(TreeView1.Items[N].Data)=T1["IDParent"] then
           begin
              DrawTree(TreeView1.Items[N]);
           end;
        end;

     end;
     T1.Next;
  end;
  end;
end;

procedure Tform1.DrawTree(Node : TTreeNode);
var
  I: Integer;
begin
  TreeView1.Items.AddChildObject(Node, T1.FieldByName("Nazvanie").AsString, Pointer(T1.FieldByName("ID").AsInteger));
end;


 
webpauk   (2006-02-06 15:56) [9]


> Digitman ©   (06.02.06 15:51) [7]
>
> > которая не сортирована по ID и IDPartner
>
>
> Что же мешает отсортировать ?


подскажи по какому полю сортировать в представленной выше таблице?


 
Digitman ©   (2006-02-06 15:57) [10]


> классический метод отрисовки


Это что за метод ?


 
webpauk   (2006-02-06 15:58) [11]

кругом такая фигня описана для рисования Ttreeview из базы данных


 
Digitman ©   (2006-02-06 15:59) [12]


> по какому полю сортировать в представленной выше таблице?


по IDParent


 
Digitman ©   (2006-02-06 16:00) [13]


> кругом такая фигня описана для рисования Ttreeview из базы
> данных


"Кругом" это где ?
Дай ссылку на образчик "фигни" ..


 
webpauk   (2006-02-06 16:02) [14]

по IDParent - не получается.
если IDParent создается ПОСЛЕ текущего Node, то владельцем найти такой ParenNode нет возможности (он еще не создан)


 
Digitman ©   (2006-02-06 16:15) [15]


> по IDParent - не получается


Все замечательно получается.


 
webpauk   (2006-02-06 16:26) [16]


> Digitman ©   (06.02.06 16:15) [15]


ID  IDParent
1 - 0
4 - 1
5 - 2
2 - 4
3 - 4

отсортировано?
куда попадет  ID=5?


 
Ega23 ©   (2006-02-06 16:28) [17]


> классический метод отрисовки дерева неправильно отображает
> представленную таблицу


Эх... На, держи...
Работает только с наборами данных, которые "отфетчены" до конца.


unit uKdrDBTreeView;

interface

uses Windows, SysUtils, Classes, comctrls, stdctrls, db, graphics, controls,
    Dialogs, contnrs;

Type

TCustomKdrDBTreeView=class;

TKdrTVChangedEvent = procedure(Sender: TObject; Node: TTreeNode;
                               var DoLocate:Boolean) of object;

TKdrDBTreeViewItemIdent = class(TObject)
 private
   FParentKeyFieldValue: Variant;
   FKeyFieldValue: Variant;
   FDisplayFieldValue: String;
   FNode: TTreeNode;
   FImage: TBitmap;
   FImageIndex: Integer;
 public
   constructor Create;
   destructor Destroy; override;

   property KeyFieldValue:Variant Read FKeyFieldValue Write FKeyFieldValue;
   property ParentKeyFieldValue:Variant Read FParentKeyFieldValue Write FParentKeyFieldValue;
   property DisplayFieldValue:String Read FDisplayFieldValue Write FDisplayFieldValue;
   property ImageIndex:Integer Read FImageIndex Write FImageIndex;
   property Image:TBitmap Read FImage Write FImage;
   property Node:TTreeNode Read FNode Write FNode;
end;

TTreeDataLink = class(TDataLink)
 private
   FTree: TCustomKdrDBTreeView;
   FMinParent: Variant;
   FMinValue: Variant;

 public
   constructor Create(ATree:TCustomKdrDBTreeView);
   procedure DataSetChanged; override;
   procedure ActiveChanged; override;
   procedure RecordChanged(Field: TField); override;
   procedure UpdateData; override;

   property MinParent:Variant Read FMinParent Write FMinParent;
   property MinValue:Variant Read FMinValue Write FMinValue;

end;

TCustomKdrDBTreeView = class(TCustomTreeView)
 private
   FButtonSize: Integer;

   FImageList:TImageList;
   FDataLink: TTreeDataLink;
   FTreeItems:TObjectList;
   FKeyField: String;
   FDisplayField: String;
   FParentField: String;
   FDataSource: TDataSource;
   FTVOnChange: TKdrTVChangedEvent;
   Inh_TVCustomDrawItem:  TTVCustomDrawItemEvent;
   FImageField: String;
   FCallUsers_OnChange:Boolean;
   procedure SetFDataSource(const Value: TDataSource); virtual;
   procedure SetFImageField(const Value: String);
   function GetFKeyValue: Variant;

 protected

   function LocateByNode(Node:TTreeNode):Boolean;
   procedure TVChange(Sender: TObject; Node: TTreeNode);
   procedure AddAllNodes(ParentID: Variant; ParentNode:TTreeNode);
   procedure TVCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode;
                              State: TCustomDrawState; var DefaultDraw: Boolean);

   function SetSelectedNode(const Value:Variant):TTreeNode;
   property DataSource:TDataSource Read FDataSource Write SetFDataSource;
   property DisplayField:String Read FDisplayField Write FDisplayField;
   property KeyField:String Read FKeyField Write FKeyField;
   property ParentField:String Read FParentField Write FParentField;
   property ImageField:String Read FImageField Write SetFImageField;
   property KeyValue:Variant Read GetFKeyValue;
   property OnChangeNode: TKdrTVChangedEvent Read FTVOnChange Write FTVOnChange;

 protected
   procedure DataChanged; virtual;
   procedure ActiveChanged; virtual;
   procedure RecordChanged(Field: TField); virtual;
   procedure UpdateData; virtual;

 public

   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
   procedure Clear;

   function AddItem:Integer;
end;

TKdrDBTreeView = class (TCustomKdrDBTreeView)
 published
  property DataSource;
  property DisplayField;
  property KeyField;
  property ParentField;
  property ImageField;
  property KeyValue;
  property OnChangeNode;
  property OnClick;
end;



 
Ega23 ©   (2006-02-06 16:29) [18]


implementation

//*****************************************************************************

{ TKdrDBTreeViewItemIdent }

constructor TKdrDBTreeViewItemIdent.Create;
begin
Image:=nil;
ImageIndex:=-1;
end;

//*****************************************************************************

destructor TKdrDBTreeViewItemIdent.Destroy;
begin
 if Assigned(Image) then Image.Free;
 inherited;
end;

{ TTreeDataLink }

//*****************************************************************************

procedure TTreeDataLink.ActiveChanged;
var
i:Integer;
begin
 inherited;
 FTree.Clear;
 if Assigned(DataSet) and (DataSet.Active) and (FTree<>nil) and
    (dsBrowse in [DataSet.State]) then
  begin
   BufferCount:=DataSet.RecordCount;
   i:=0;
   ActiveRecord:=i;
   MinParent:=DataSet.FieldByName(FTree.KeyField).Value;
   MinValue:=DataSet.FieldByName(FTree.ParentField).Value;

   While (i<BufferCount) do
    begin
     FTree.AddItem;
     With DataSet do
      begin
       if MinValue>FieldByName(FTree.KeyField).Value then
        MinValue:=FieldByName(FTree.KeyField).Value;
       if MinParent>FieldByName(FTree.ParentField).Value then
        MinParent:=FieldByName(FTree.ParentField).Value;
      end;
     Inc(i);
     ActiveRecord:=i;
    end;
   FTree.ActiveChanged;
   ActiveRecord:=0;
  end;
end;

//*****************************************************************************

constructor TTreeDataLink.Create(ATree: TCustomKdrDBTreeView);
begin
 inherited Create;
 FTree:=ATree;
 VisualControl:=True;
end;

//*****************************************************************************

procedure TTreeDataLink.DataSetChanged;
begin
 inherited;
 if (DataSet.Active) and (FTree<>nil) and (dsBrowse in [DataSet.State]) then
  FTree.DataChanged;
end;

//*****************************************************************************

procedure TTreeDataLink.RecordChanged(Field: TField);
begin
 inherited;
 if Assigned(DataSet) and (DataSet.Active) and (FTree<>nil) and
    (dsBrowse in [DataSet.State]) then
  FTree.RecordChanged(Field);
end;

procedure TTreeDataLink.UpdateData;
begin
 inherited;
 if (DataSet.Active) and (FTree<>nil) then
 FTree.UpdateData;
end;

//*****************************************************************************


 
Ega23 ©   (2006-02-06 16:30) [19]


{ TKdrDBTreeView }

procedure TCustomKdrDBTreeView.ActiveChanged;
begin
 Items.BeginUpdate;
 AddAllNodes(FDataLink.MinParent, nil);
 Items.EndUpdate;
end;

//*****************************************************************************

procedure TCustomKdrDBTreeView.AddAllNodes(ParentID: Variant;
 ParentNode: TTreeNode);
var
k:Integer;
CurrNode:TTreeNode;
begin
for k:=0 to FTreeItems.Count-1 do
 begin
  With TKdrDBTreeViewItemIdent(FTreeItems.Items[k]) do
   begin
    if (Node<>nil) or (ParentKeyFieldValue<>ParentID) then Continue;
    if ParentNode=nil then
     CurrNode:=Items.Add(nil, DisplayFieldValue)
    else
     CurrNode:=Items.AddChild(ParentNode, DisplayFieldValue);
     CurrNode.ImageIndex:=ImageIndex;
     CurrNode.SelectedIndex:=ImageIndex;
    Node:=CurrNode;
    CurrNode.Data:=FTreeItems.Items[k];
    AddAllNodes(KeyFieldValue, CurrNode);
   end; // With
 end; // for

end;

//*****************************************************************************

function TCustomKdrDBTreeView.AddItem: Integer;
var
ms:TMemoryStream;
begin
try
 Result:=FTreeItems.Add(TKdrDBTreeViewItemIdent.Create);
 With TKdrDBTreeViewItemIdent(FTreeItems.Items[Result]) do
  begin
   KeyFieldValue:=FDataLink.DataSet.FieldByName(KeyField).Value;
   ParentKeyFieldValue:=FDataLink.DataSet.FieldByName(ParentField).Value;
   DisplayFieldValue:=FDataLink.DataSet.FieldByName(DisplayField).AsString;
   if (ImageField<>"") then
    if not (FDataLink.DataSet.FieldByName(ImageField).IsNull) then
     begin
      ms:=TMemoryStream.Create;
      try
       TBLOBField(FDataLink.DataSet.FieldByName(ImageField)).SaveToStream(ms);
       ms.Position:=0;
       Image:=TBitmap.Create;
       try
        Image.LoadFromStream(ms);
        ImageIndex:=FImageList.Add(Image, nil);
       except
        ImageIndex:=-1;
       end;
      finally
       ms.Free;
      end;
     end;
  end;
except
 Result:=-1;
end;

end;

//*****************************************************************************

procedure TCustomKdrDBTreeView.Clear;
begin
 FTreeItems.Clear;
 if Assigned(FImageList) then FImageList.Clear;
 Items.Clear;
end;

//*****************************************************************************

constructor TCustomKdrDBTreeView.Create(AOwner: TComponent);
begin
 inherited;
 HideSelection:=False;
 ParentFont:=True;
 FButtonSize:=5;
 ReadOnly:=True;

 FDataLink:=TTreeDataLink.Create(Self);
 FTreeItems:=TObjectList.Create(True);

 //if Assigned(Self.OnChange) then FTVOnChange:=Self.OnChange;
 //if Assigned(Self.OnCustomDrawItem) then Inh_TVCustomDrawItem:=Self.OnCustomDrawItem;
 Self.OnChange:=TVChange;
 //Self.OnCustomDrawItem:=TVCustomDrawItem;

end;

//*****************************************************************************

procedure TCustomKdrDBTreeView.DataChanged;
begin
FCallUsers_OnChange:=False;
Selected:=SetSelectedNode(FDataLink.DataSet.FieldByName(KeyField).AsInteger);
FCallUsers_OnChange:=True;
end;

//*****************************************************************************

destructor TCustomKdrDBTreeView.Destroy;
begin

 FTreeItems.Free;
 FDataLink.Free;

 inherited;
end;

//*****************************************************************************

function TCustomKdrDBTreeView.GetFKeyValue: Variant;
begin
 Result:=FDataLink.DataSet.FieldByName(KeyField).AsVariant;
end;

//*****************************************************************************

function TCustomKdrDBTreeView.LocateByNode(Node: TTreeNode): Boolean;
var
i:Integer;
V:Variant;
keyFields:String;
begin
Result:=False;
for i:=0 to FTreeItems.Count-1 do
 if TKdrDBTreeViewItemIdent(FTreeItems.Items[i]).Node=Node then
  begin
   V:=VarArrayCreate([0,1], varVariant);
   V[0]:=TKdrDBTreeViewItemIdent(FTreeItems.Items[i]).KeyFieldValue;
   V[1]:=TKdrDBTreeViewItemIdent(FTreeItems.Items[i]).ParentKeyFieldValue;
   keyFields:=KeyField+";"+ParentField;
   Result:=FDataLink.DataSet.Locate(KeyFields,V , []);
  end;
end;

//*****************************************************************************

procedure TCustomKdrDBTreeView.RecordChanged(Field: TField);
begin

end;

//*****************************************************************************

procedure TCustomKdrDBTreeView.UpdateData;
begin

end;

//*****************************************************************************

procedure TCustomKdrDBTreeView.SetFDataSource(const Value: TDataSource);
begin
 if (Value<>nil) and (FDataSource<>Value) then
  begin
   FDataSource := Value;
   FDataLink.DataSource:=Value;
  end;
end;

//*****************************************************************************

procedure TCustomKdrDBTreeView.SetFImageField(const Value: String);
begin
 FImageField := Value;
 if not Assigned(FImageList) then
  begin
   FImageList:=TImageList.CreateSize(16, 16);
   FImageList.Masked:=False;
   Self.Images:=FImageList;
  end;
end;

//*****************************************************************************

function TCustomKdrDBTreeView.SetSelectedNode(
 const Value: Variant): TTreeNode;
var
i:Integer;
begin
Result:=nil;
for i:=0 to FTreeItems.Count-1 do
 With TKdrDBTreeViewItemIdent(FTreeItems.Items[i]) do
  if KeyFieldValue=Value then
   begin
    Result:=Node;
    Break;
   end;
end;

//*****************************************************************************

procedure TCustomKdrDBTreeView.TVChange(Sender: TObject; Node: TTreeNode);
var
DoLocate:Boolean;
begin
 DoLocate:=FCallUsers_OnChange;

 LocateByNode(Node);

 if DoLocate then
    if (@FTVOnChange<>nil) then FTVOnChange(Sender, Node, DoLocate);

//  if DoLocate then LocateByNode(Node);

end;

//*****************************************************************************

procedure TCustomKdrDBTreeView.TVCustomDrawItem(Sender: TCustomTreeView;
 Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var
i:Integer;
KdrDBTreeViewItem:TKdrDBTreeViewItemIdent;
NodeRect:TRect;
begin

 for i:=0 to FTreeItems.Count-1 do
  begin
   KdrDBTreeViewItem:=TKdrDBTreeViewItemIdent(FTreeItems.Items[i]);
   if KdrDBTreeViewItem.Node=Node then
    begin
     if Assigned(KdrDBTreeViewItem.Image) then
     //if Assigned(KdrDBTreeViewItem) then
      begin
       //Self.Canvas.Font.Assign

       NodeRect:=Node.DisplayRect(True);

       NodeRect.Left := NodeRect.Left + 16; //ImageList.Width;

       Canvas.Font.Name:="MS Sans Serif";
       Canvas.Font.Size:=8;
       Font.Name:="MS Sans Serif";
       Font.Size:=8;

       Canvas.TextOut(NodeRect.Left, NodeRect.Top, Node.Text);

       //ShowMessage("Font Size = "+IntToStr(Self.Canvas.Font.size));
       //DefaultDraw:=False;
      end;
     Break; // &#194;&#251;&#245;&#238;&#228; &#232;&#231; &#246;&#232;&#234;&#235;&#224; &#237;&#224;&#245;&#240;&#229;&#237;.
    end;

  end;

if Assigned(Inh_TVCustomDrawItem) then Inh_TVCustomDrawItem(Sender, Node, State, DefaultDraw);

end;

//*****************************************************************************

end.


 
webpauk   (2006-02-06 16:36) [20]

VarArrayCreate?


 
Digitman ©   (2006-02-06 16:39) [21]


> webpauk   (06.02.06 16:26) [16]


А кто или что заставляет тебя использовать один-единственный НД, формируемый одним-единственным запросом, для заполнения TreeView ?


 
webpauk   (2006-02-06 16:42) [22]


> Digitman ©   (06.02.06 16:39) [21]

что есть НД?
уточни.


 
webpauk   (2006-02-06 16:45) [23]


> Ega23 ©  

VarArrayCreate?


 
Digitman ©   (2006-02-06 16:46) [24]


> что есть НД?


НД = Набор Данных


 
webpauk   (2006-02-06 16:49) [25]


> Ega23 ©  

VarArrayCreate?

sorry
unit Variants


 
webpauk   (2006-02-06 16:49) [26]


> Digitman ©   (06.02.06 16:46) [24]

пример?!


 
Digitman ©   (2006-02-06 16:52) [27]

в стандартных


 
webpauk   (2006-02-06 16:56) [28]


> Ega23 ©  

спсб



Страницы: 1 вся ветка

Текущий архив: 2006.02.26;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.038 c
3-1135861106
linx
2005-12-29 15:58
2006.02.26
Чтобы сервер InterBase стартовал раньше ввода пароля


15-1139291447
DelphiN!
2006-02-07 08:50
2006.02.26
Соединение с сервером происходит только после его пинга


15-1139304455
dr Tr0jan
2006-02-07 12:27
2006.02.26
Выбираю телевизор


4-1133908355
Volf_555
2005-12-07 01:32
2006.02.26
Как получить строковое значение функции CreateGUID()?


15-1139263058
Цукор5
2006-02-07 00:57
2006.02.26
С++