TreeView, ListView
Code: |
{type {: Callback to use to copy the data of a treenode when the node itself is copied by CopySubtree. @param oldnode is the old node @param newnode is the new node @Desc Use a callback of this type to implement your own algorithm for a node copy. The default just uses the Assign method, which produces a shallow copy of the nodes Data property. } TCopyDataProc = procedure(oldnode, newnode : TTreenode);
{: The default operation is to do a shallow copy of the node, via Assign. } procedure DefaultCopyDataProc(oldnode, newnode : TTreenode); begin newnode.Assign(oldnode); end;
{-- CopySubtree -------------------------------------------------------} {: Copies the source node with all child nodes to the target treeview. @Param sourcenode is the node to copy @Param target is the treeview to insert the copied nodes into @Param targetnode is the node to insert the copy under, can be nil to make the copy a top-level node. @Param CopyProc is the (optional) callback to use to copy a node. If Nil is passed for this parameter theDefaultCopyDataProc will be used. @Precondition sourcenode <> nil, target <> nil, targetnode is either nil or a node of target @Raises Exception if targetnode happens to be in the subtree rooted in sourcenode. Handling that special case is rather complicated, so we simply refuse to do it at the moment. }{ Created 2003-04-09 by P. Below ----------------------------------------------------------------------- } procedure CopySubtree(sourcenode : TTreenode; target : TTreeview; targetnode : TTreenode; CopyProc : TCopyDataProc = nil); var anchor : TTreenode; child : TTreenode; begin { CopySubtree } Assert(Assigned(sourcenode), 'CopySubtree:sourcenode cannot be nil'); Assert(Assigned(target), 'CopySubtree: target treeview cannot be nil'); Assert((targetnode = nil) or (targetnode.TreeView = target), 'CopySubtree: targetnode has to be a node in the target treeview.');
if (sourcenode.TreeView = target) and (targetnode.HasAsParent(sourcenode) or (sourcenode = targetnode)) then raise Exception.Create('CopySubtree cannot copy a subtree to one of the ' + 'subtrees nodes.');
if not Assigned(CopyProc) then CopyProc := DefaultCopyDataProc;
anchor := target.Items.AddChild(targetnode, sourcenode.Text); CopyProc(sourcenode, anchor); child := sourcenode.GetFirstChild; while Assigned(child) do begin CopySubtree(child, target, anchor, CopyProc); child := child.getNextSibling; end; { While } end; { CopySubtree }
procedure TForm1.Button1Click(Sender : TObject); begin if assigned(treeview1.selected) then CopySubtree(treeview1.selected, treeview2, nil); end; |
- Подробности
- Родительская категория: TreeView, ListView
- Категория: TTreeView
Code: |
unit BetterTreeView;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, CommCtrl;
type TTVNewEditCancelEvent = procedure( Sender: TObject; Node: TTreeNode; var Delete: Boolean) of object; TBetterTreeView = class(TTreeView) protected FIsEditingNew: Boolean; FOnEditCancel: TTVChangedEvent;
FOnNewEditCancel: TTVNewEditCancelEvent; procedure Edit(const Item: TTVItem); override; public function NewChildAndEdit(Node: TTreeNode; const S: String) : TTreeNode; published property IsEditingNew: Boolean read FIsEditingNew; property OnEditCancel: TTVChangedEvent read FOnEditCancel write FOnEditCancel; property OnNewEditCancel: TTVNewEditCancelEvent read FOnNewEditCancel write FOnNewEditCancel; end;
implementation
procedure TBetterTreeView.Edit(const Item: TTVItem); var Node: TTreeNode; Action: Boolean; begin with Item do begin { Get the node } if (state and TVIF_PARAM) <> 0 then Node := Pointer(lParam) else Node := Items.GetNode(hItem);
if pszText = nil then begin if FIsEditingNew then begin Action := True; if Assigned(FOnNewEditCancel) then FOnNewEditCancel(Self, Node, Action); if Action then
Node.Destroy end else if Assigned(FOnEditCancel) then FOnEditCancel(Self, Node); end else fFinherited; end; FIsEditingNew := False; end;
function TBetterTreeView.NewChildAndEdit (Node: TTreeNode; const S: String): TTreeNode; begin SetFocus; Result := Items.AddChild(Node, S); FIsEditingNew := True; Node.Expand(False); Result.EditText; SetFocus; end;
end. |
- Подробности
- Родительская категория: TreeView, ListView
- Категория: TTreeView
Code: |
{ Treeview1.SaveToFile('...') doesn't store images. Instead, use the code below. }
// Save
procedure TForm1.Button1Click(Sender: TObject); var F: TFileStream; begin F := TFileStream.Create('c:\TreeView.txt', fmCreate or fmShareCompat); try F.WriteComponent(TreeView1); finally F.Free; end; end;
// Load
procedure TForm1.Button2Click(Sender: TObject); var F: TFileStream; begin F := TFileStream.Create('c:\TreeView.txt', fmOpenRead or fmShareDenyWrite); try F.ReadComponent(TreeView1); finally F.Free; end; end; |
- Подробности
- Родительская категория: TreeView, ListView
- Категория: TTreeView
Code: |
uses ComCtrls, Menus, Classes, Forms, Controls, Windows, Messages;
function GetControlCaption(Control: TWinControl): ShortString; // Slightly modified version of Twister's Tip // // function GetCaptionAtPoint(pt: TPoint): string; // var TextLength: Integer; Text: PChar; begin if not Boolean(Control.Handle) then Exit;
Result := Control.Name; // if Control doesn't have Caption // Control.Name is returned
TextLength := SendMessage(Control.Handle, WM_GETTEXTLENGTH, 0, 0); if TextLength 0 then begin GetMem(Text, TextLength + 1); SendMessage(Control.Handle, WM_GETTEXT, TextLength + 1, Integer(Text)); Result := Text; FreeMem(Text); end; end;
// function GetCaptionAtPoint(pt: TPoint): ShortString; // begin // Result:= GetControlCaption(FindVCLWindow(pt)); // end;
procedure FindAllMenuItems(AppTree: TTreeView; MenuItem: TMenuItem; Parent: TTreeNode); var loop: Integer; Node: TTreeNode; mItem: TMenuItem; Name: ShortString; begin for loop := 0 to MenuItem.Count - 1 do begin mItem := MenuItem.Items[loop]; Name := mItem.Caption; Node := AppTree.Items.AddChildObject(Parent, Name, mItem); if mItem.Count 0 then findAllMenuItems(AppTree, mItem, Node); end; end;
procedure FindAllControls(AppTree: TTreeView; Comp: TComponent; Parent: TTreeNode); var Child: TComponent; loop, start, Index: Integer; Name: ShortString; Node, Mnode: TTreeNode; begin start := 0; if Comp is TApplication then begin // Parent:= AppTree.Items.AddObjectFirst(Parent, 'Application', nil); // if you want to see the root ('Application') uncomment start := 1; end;
for loop := start to Comp.ComponentCount - 1 do begin Child := Comp.Components[loop]; Name := Child.Name;
if Child is TControl then begin if Child is TWinControl then begin // does Child have Caption property?? Name := GetControlCaption(TWinControl(Child)); end; Node := AppTree.Items.AddChildObject(Parent, Name, Child); if Child.ComponentCount 0 then FindAllControls(AppTree, Child, Node); end;
if Child is TMenu then begin Node := AppTree.Items.AddChildObject(Parent, Name, Child); for Index := 0 to TMenu(Child).Items.Count - 1 do begin Mnode := AppTree.Items.AddChildObject(Node, TMenu(Child).Items[Index].Caption, TMenu(Child).Items[Index]); FindAllMenuItems(AppTree, TMenu(Child).Items[Index], Mnode); end; end; end; end; |
- Подробности
- Родительская категория: TreeView, ListView
- Категория: TTreeView
Представляем вашему вниманию немного переработанный компонент TreeView, работающий быстрее своего собрата из стандартной поставки Delphi. Кроме того, была добавлена возможность вывода текста узлов и пунктов в жирном начертании (были использованы методы TreeView, хотя, по идее, необходимы были свойства TreeNode. Мне показалось, что это будет удобнее).
Для сравнения:
TreeView:
128 сек. для загрузки 1000 элементов (без сортировки)*
270 сек. для сохранения 1000 элементов (4.5 минуты!!!)
HETreeView:
- Подробности
- Родительская категория: TreeView, ListView
- Категория: TTreeView
Автор: Mike Scott
На пустой форме у меня располагается TTreeView. Затем я сохраняю это в файле, используя WriteComponent. Это работает как положено; я могу из DOS c помощью команды "type" посмотреть двоичный файл и увидеть его содержимое, типа строк TTreeView и имя объекта. По крайней мере файл записывается и создается впечатление его "наполненности".
Затем я освобождаю компонент TTreeView, открываю поток, делаю ReadComponent и, затем, InsertControl. И получаю исключение "TreeView1 has no parent window" (TreeView1 не имеет родительского окна).
- Подробности
- Родительская категория: TreeView, ListView
- Категория: TTreeView
Code: |
function IsTreeviewFullyExpanded(tv: TTreeview): Boolean; var Node: TTreeNode; begin Assert(Assigned(tv)); if tv.Items.Count > 0 then begin Node := tv.Items[0]; Result := True; while Result and Assigned(Node) do begin Result := Node.Expanded or not Node.HasChildren; Node := Node.GetNext; end; {While} end {If} else Result := False end;
function IsTreeviewFullyCollapsed(tv: TTreeview): Boolean; var Node: TTreeNode; begin Assert(Assigned(tv)); if tv.Items.Count > 0 then begin Node := tv.Items[0]; Result := True; while Result and Assigned(Node) do begin Result := not (Node.Expanded and Node.HasChildren); Node := Node.GetNext; end; {While} end {If} else Result := False end; |
- Подробности
- Родительская категория: TreeView, ListView
- Категория: TTreeView
Code: |
// Search a TreeItem through its Text property // Return value is a TreeNodeObject function Form1.TreeItemSearch(TV: TTreeView; SucheItem: string): TTreeNode; var i: Integer; iItem: string; begin if (TV = nil) or (SucheItem = '') then Exit; for i := 0 to TV.Items.Count - 1 do begin iItem := TV.Items[i].Text; if SucheItem = iItem then begin Result := TV.Items[i]; Exit; end else begin Result := nil; end; end; end; |
- Подробности
- Родительская категория: TTreeView
- Категория: Поиск и путь к узлу
Нужно использовать рекурсивные механизмы спуска по дереву и иметь метод определения наличия child узлов у текущего узла.
Code: |
function TDBTreeView.RecurseChilds(node: TTreeNode): double; begin while node <> nil do begin if node.HasChildren then Result := RecurseChilds(node.GetFirstChild); Result := Result + GetResultForNode(node)); node := node.GetNextSibling; end; end;
function TDBTreeView.GetResult(curnode: TTreeNode;): double; begin Result := 0; if curnode = nil then Exit; Result := RecurseChilds(curnode.GetFirstChild); end; |
- Подробности
- Родительская категория: TreeView, ListView
- Категория: TTreeView
Code: |
{ **** UBPFD *********** **** >> Получение узла в TreeView по пути заголовков
Функция выдает узел TTreeNode из дерева TreeView, находящийся по пути, указанному в Path, в котором разделителем уровней является символ Separator. Если узел не найден - выдается nil. Ограничение - заголовки узлов дерева не должны содержать символа Separator.
Зависимости: ComCtrls, Classes, SysUtils Автор: lipskiy, Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра., ICQ:51219290, Санкт-Петербург Copyright: Собственное написание (lipskiy) ***************************************************** }
function GetNodeInPath(Path: string; Separator: char; TreeView: TTreeView): TTreeNode; var List: TStringList; Node: TTreeNode; i: integer; s: string; begin Result := nil; if (TreeView = nil) or (TreeView.Items.Count = 0) or (Path = '') or (Separator = '') then exit; List := TStringList.Create; // Меняем сепаратор на первод строки s := StringReplace(Path, Separator, #13#10,[rfReplaceAll]); // Получаем список уровней List.Text := s; // Начинаем с нулевой ноды дерева Node := TreeView.Items[0]; // Проходим по всему списку уровней пути for i := 0 to List.Count - 1 do begin // Ищем имя ноды на текущем уровне while (Node <> nil) and (Node.Text <> List[i]) do Node := Node.getNextSibling; // Нода не найдена if Node = nil then break; // Переходим на уровень ниже if i < List.Count - 1 then Node := Node.getFirstChild; end; List.Free; Result := Node; end;
// Пример использования: procedure TForm1.Button1Click(Sender: TObject); begin TreeView1.Selected := GetNodeInPath('Каталог\Подкаталог', '\', TreeView1); end; |
- Подробности
- Родительская категория: TTreeView
- Категория: Поиск и путь к узлу
Страница 2 из 3