delphi中treeview的用法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi中treeview的用法相关的知识,希望对你有一定的参考价值。

如何用treeview实现树型结构目录,表里有fatherID字段,我是delphi新手,有人能给我详细说一下吗
我的情况是,我能把所有数据取到结果集,就是不知道怎么按fatherid在treeview里直接按树型显示出来,如果你能给个简单的例子和注释就太感谢了

例一

//刷新Tree 1
procedure TMainForm.RefTree();
var
Tags:string ;
RootNode0,RootNode1,RootNode2,RootNode3,RootNode4,RootNode5:TtreeNode;
i:integer;
begin
TreeView1.Items.Clear;

RootNode0:=TreeView1.Items.Add(nil,'全部');
RootNode1:=TreeView1.Items.Add(nil,'资分类');
RootNode2:=TreeView1.Items.Add(nil,'部门');
RootNode3:=TreeView1.Items.Add(nil,'情况');
RootNode4:=TreeView1.Items.Add(nil,'位置');
RootNode5:=TreeView1.Items.Add(nil,'方式');
TreeView1.Items[0].ImageIndex:=11;
TreeView1.Items[1].ImageIndex:=54;
TreeView1.Items[2].ImageIndex:=54;
TreeView1.Items[3].ImageIndex:=54;
TreeView1.Items[4].ImageIndex:=54;
TreeView1.Items[5].ImageIndex:=54;
RootNode0.SelectedIndex:=RootNode0.ImageIndex;
RootNode1.SelectedIndex:=RootNode1.ImageIndex;
RootNode2.SelectedIndex:=RootNode2.ImageIndex;
RootNode3.SelectedIndex:=RootNode3.ImageIndex;
RootNode4.SelectedIndex:=RootNode4.ImageIndex;
RootNode5.SelectedIndex:=RootNode5.ImageIndex;

//分类
with DataM.q1 do
begin
SQL.Clear;
SQL.Add('Select Name1 from Navtree where tag=''分类'' ');
Open;
while not eof do
begin
TreeView1.Items.AddChild(RootNode1,FieldValues['Name1']);
next;
end;
end;
(此处省略365个字.....呵呵)

end;

例二

procedure TForm1.showtree; //showtree自定义的
var
mynode:ttreenode;
begin
with adoquery1 do
begin
close;
sql.Clear;
sql.Add('select * from aa where value = ''1''');
open;
if recordcount <> 0 then
begin
treeview1.Items.Add(treeview1.TopItem,fieldbyname('name').AsString);
end;
end;

with adoquery2 do
begin
close;
sql.Clear;
sql.Add('select * from aa where len(name) = 4');
open;
while not eof do
begin
mynode:= treeview1.Items.AddChild(treeview1.TopItem,fieldbyname('name').AsString);
with adoquery3 do
begin
close;
sql.Clear;
sql.Add('select * from aa where name like '''+ '%'+ mynode.Text+ ''' and len(name) = 6');
open;
if recordcount <> 0 then
begin
first;
begin
treeview1.Items.AddChild(mynode,fieldbyname('name').AsString);
next;
end;
end;
end;
next;
end;
end;
end

例三

一、指标树的建立

具体方法是:创建一个数据库,设计指标表t_pub_index,包含index_id、parent_id、index_name字段,其它字段根据实际业务而定,指标名称index_name将在树型控件的节点上显示,index_id字段保存节点的唯一标识号,parent_id表示当前节点的父节点号,标识号组成了一个“链表”,记录了树上节点的结构。设计一窗体Frm_sys_index,其上放置TreeView控件tv_zb、Query控件Query1及其它指标属性编辑显示控件。一个树的节点又包含文本(Text)和数据(Data)。Text为String类,用来显示指标或指标目录名称。Data则为无定形指针(Untyped Pointer),可以指向一个与节点相联系的数据结构,该结构与数据库指标表相应域关联,如指标ID、上级节点ID。

Query控件的表达式为:

select index_id, parent_id, index_name from t_pub_index

start with index_id=0 connect by prior index_id=parent_id

其中start with 和connect by 是Oracle的SQL语句的保留字,使一条记录的parent_id列的值等于前一记录的index_id列的值,并以parent_id等于0的记录开始。

建树的基本思路是:

procedure TFrm_sys_index.createtree;

var

curValue: indexPointer; //指向与节点相联系的数据结构的指针

curNode : TTreeNode; //当前节点

curid : integer; //当前节点标识号

begin

curNode := nil;

curid := -1;

Query_index.Open;

Query_index.first;

while not Query_index.Eof do

begin

new(curValue);

With curValue^ do

将数据库指标表t_pub_index各字段值赋curValue 所指数据结构

while(curid <> curValue.parent_id) do //当前节点的标识号不等于当前记录的父节点号

begin

curNode := curNode.parent;

curid:= indexPointer(curNode.data).index_id;

end;

curNode := tv_zb.Items.AddChildObject(curNode,

curValue^.index_name,curValue); //在当前节点上添加子节点,显示节点指标名称,所带指针指向一个与指标数据相联系的数据结构

curid := indexPointer(curNode.data).index_id;

Query_index.next;

end;

Query_index.close;

end;

二、增加、删除、修改树节点

单纯在Treeview 上增加、删除、修改节点只需用它本身提供的Treeview.Items. AddChildObject、 Treeview.Selected.Delete、Treeview.Selected.EditText等方法即可,但要相应修改数据库中的数据,必须通过递归调用同一个函数(用于删除一个选项)来遍历所选节点下的所有子节点。下面以删除节点为例介绍具体实现流程:

function TFrm_sys_index.delnode(node1:TTreenode):TTreenode;

var

childnode:TTreenode;

begin

childnode:=node1.GetLastChild; //按倒序获得子项,因为删除选项时,列表会发生变化

while childnode<>nil do

childnode:=delnode(childnode); //如子项不为空,进行递归调用

index_id:=inttostr(indexpointer(node1.data).index_id);//获得该节点对应指标

在数据库删除相应指标;

result:=node1.parent.GetPrevChild(node1); //定位到该节点的上一节点

node1.delete; //删除树节点

end;

三、拖动树节点

拖动树节点基本上是通过建立目标项的新子项、向它复制源项、删除原项来移动选项。与上述删除操作相似,也是通过递归调用同一个函数(用于移动一个选项),按倒序移动所选节点下的所有子节点。下面是递归过程的代码:

procedure TFrm_sys_index.CopyNodeUnder(treeview:TTreeview;

sourcenode,targetnode:ttreenode);

var

newnode:ttreenode;

i:integer;

begin

newnode:=treeview.items.addchildfirst(targetnode,''); //建立目标项

newnode.assign(sourcenode); //复制源项属性

for i:=sourcenode.count-1 downto 0 do //递归调用,按倒序移动其所有子项

CopyNodeUnder (treeview,sourcenode.item[i],newnode);

treeview.items.delete(sourcenode); //删除源项

end;

Treeview对拖动操作提供支持,我们将组件的DragKind属性设置为dkDrag,DragMode属性设置为dmAutomatic,并为OnDragOver与OnDragDrop事件编写了处理程序。OnDragOver事件处理程序对允许移动的条件进行判断,排除需要避免的特殊情况。代码如下:

procedure TFrm_sys_index.tv_zbDragOver(Sender, Source: TObject; X,

Y: Integer; State: TDragState; var Accept: Boolean);

var

targetnode,sourcenode:TTreenode;

begin

targetnode:=tv_zb.getnodeat(x,y);

if (Source=Sender) and (targetnode<>nil) then //保证移动在TreeView上,且目标节点不为空

begin

Accept:=true;

sourcenode:=tv_zb.selected;

//以下代码防止用户将一个选项拖到其子项上(它会随着选项一起移动,导致死循环)

while (targetnode.parent<>nil) and (targetnode <> sourcenode) do

targetnode:=targetnode.parent;

if (targetnode = sourcenode) then Accept:=false;

end

else Accept:=false;

end;

OnDragDrop事件处理程序启动前述移动过程CopyNodeUnder,修改数据库数据。此外,在大批量添加数据到Treeview中时最好使用TreeView.Items.BeginUpdate和 TreeView.Items.EndUpdate,这样能加快显示速度。大致流程如下:

procedure TFrm_sys_index.tv_zbDragDrop(Sender, Source: TObject; X,

Y: Integer);

var

targetnode,sourcenode:TTreenode;

begin

targetnode:=tv_zb.getnodeat(x,y); //获得源节点

sourcenode:=tv_zb.selected; //获得目标节点

修改数据库中当前节点的父节点号parent_id,使其等目标节点标识号;

tv_zb.items.beginupdate; //禁用TreeView重绘操作

try

copynodeunder(tv_zb,sourcenode,targetnode); //启动移动过程

tv_zb.selected:=targetnode;

finally

tv_zb.items.endupdate; //重新设置

end;

end;

例四

给你一段超级短的代码,caption字段就是你的value字段,因value是保留字,所以我改成这个了。

procedure TForm1.Button1Click(Sender: TObject);
var
ss: TStrings;
begin
AdoQuery1.SQL.Text := 'SELECT name,caption FROM test8 ORDER BY name';
AdoQuery1.Open;

ss := TStringList.Create;
while not AdoQuery1.Eof do
begin
ss.Add(StringOfChar(#9,(Length(Trim(AdoQuery1.FieldValues['name'])) div 2)-1)
+ AdoQuery1.FieldValues['caption']);
AdoQuery1.Next;
end;

ShowMessage(ss.Text);
ss.SaveToFile('d:\test8.txt');
ss.Free;

TreeView1.LoadFromFile('d:\test8.txt');
end;
参考技术A 如果楼主能给个详细点的要求我能给你个例子

通常的做法就是把数据取到客户端数据集里然后根据fatherid排序,
一次加到Treeview里的

但是我不知道你的具体情况,怕举例子也不要说,楼主如果有兴趣可以hi我
参考技术B 双击你的TreeView 自己添加吧 参考技术C 常数简单示例
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls;

type
TForm1 = class(TForm)
tv1: TTreeView;
procedure FormCreate(Sender: TObject);
private
Private declarations
public
Public declarations
end;

var
Form1: TForm1;

implementation

$R *.DFM

procedure TForm1.FormCreate(Sender: TObject);
var
text:array[1..6] of string;
node:array[1..6] of TTreeNode;
begin
Text[1]:='根';
node[1]:= tv1.Items.Add(nil,Text[1]);
Text[2]:='二级根';
node[2]:=tv1.Items.AddChild(node[1],Text[2]);
Text[3]:='二级根';
node[3]:=tv1.Items.AddChild(node[1],Text[3]);
Text[4]:='三级根';
node[4]:=tv1.Items.AddChild(node[2],Text[4]);
Text[5]:='三级根';
node[5]:=tv1.Items.AddChild(node[2],Text[5]);
Text[6]:='三级根';
node[6]:=tv1.Items.AddChild(node[3],Text[5]);
end;

end.

C# WPF TreeView用法实例解析

概述

    TreeView是常用的树状列表,在项目开发中也时常会用到,这节主要讲解treeview在wpf的基本用法!

结果演示:

代码讲解

    前台xaml:

<UserControl x:Class="Caliburn.Micro.Hello.Views.TreeViewView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Caliburn.Micro.Hello.Views" 
             xmlns:self="clr-namespace:Caliburn.Micro.Hello.ViewModels" 
             xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid" 
             xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
              xmlns:cal="http://www.caliburnproject.org" 
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>


        <dxg:TreeListControl 
            ItemsSource="Binding EmployeeDepartments" 
            SelectedItem="Binding CurrentSelectedItem" Grid.Column="0" >
            <dxg:TreeListControl.View>
                <dxg:TreeListView
                            AllowColumnFiltering="False"
                            AllowConditionalFormattingMenu="False"
                            AllowFixedColumnMenu="False"
                            AllowRecursiveNodeChecking="True"
                            AutoWidth="True"
                            FetchSublevelChildrenOnExpand="False"
                            IsColumnMenuEnabled="False"
                            IsRowCellMenuEnabled="True"
                            IsTotalSummaryMenuEnabled="False"
                            KeyFieldName="Id"
                            ParentFieldName="ParentId"
                            ShowNodeImages="True"
                            ShowSearchPanelMode="Always">
                </dxg:TreeListView>
            </dxg:TreeListControl.View>
            <dxg:TreeListColumn
                        AllowEditing="False"
                        FieldName="Employees.Name"
                        Header="Binding TreeTitle" />
        </dxg:TreeListControl>


        <TreeView
                                    Grid.Column="1"
                                    Margin="10,15,10,10"
                                    ItemsSource="Binding EmployeeDepartments">
            <TreeView.ItemContainerStyle>
                <Style TargetType="x:Type TreeViewItem" />
            </TreeView.ItemContainerStyle>
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType="x:Type self:EmployeeDepartment" ItemsSource="Binding Employees">
                    <StackPanel HorizontalAlignment="Stretch" Orientation="Horizontal">
                        <CheckBox IsChecked="True"/>
                        <TextBlock
                                                    VerticalAlignment="Center"
                                                    FontSize="14"
                                                    Text="Binding Name"
                                                    TextTrimming="CharacterEllipsis" />
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
        <!--最简洁写法-->
        <TreeView Grid.Column="0" Grid.Row="1" ItemsSource="Binding EmployeeDepartments">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate  ItemsSource="Binding Employees">
                    <StackPanel>
                        <TextBlock Text="Binding Name"/>
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>


        <TreeView Grid.Column="1" Grid.Row="1" ItemsSource="Binding nodesCollection">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate  ItemsSource="Binding ChildNodes">
                    <StackPanel HorizontalAlignment="Stretch" Orientation="Horizontal">
                        <!--<dx:SimpleButton Glyph="dx:DXImage Images/Arrows/Next_16x16.png"/>-->
                        <CheckBox IsChecked="Binding IsChecked" 
                                  cal:Message.Attach="[Event Click]=[Action CheckBox_Click($source,$eventArgs)]"  />
                        <TextBlock   
                                                    VerticalAlignment="Center"
                                                    FontSize="14"
                                                    Text="Binding NodeName"
                                                    TextTrimming="CharacterEllipsis" />
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</UserControl>

后台cs代码:

using PropertyChanged;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;


namespace Caliburn.Micro.Hello.ViewModels

    public class TreeViewViewModel :  Screen, IViewModel
    
        public TreeViewViewModel()
        
            DisplayName = "TreeView";
            EmployeeDepartments = Departments.GetDepartments();


            //方法1
            //nodes = new List<TreeNode>()
            //
            //    new TreeNode() ParentID = 0,NodeID = 1,NodeName = "Chapter1",
            //     new TreeNode() ParentID = 0,NodeID = 2,NodeName = "Chapter2",
            //      new TreeNode() ParentID = 0,NodeID = 3,NodeName = "Chapter3",
            //       new TreeNode() ParentID = 1,NodeID = 4,NodeName = "Section1.1",
            //        new TreeNode() ParentID = 1,NodeID = 5,NodeName = "Section1.2",
            //            new TreeNode() ParentID = 2,NodeID = 6,NodeName = "Section2.1",
            //     new TreeNode() ParentID = 3,NodeID = 7,NodeName = "Section3.1",
            //      new TreeNode() ParentID = 6,NodeID = 8,NodeName = "SubSection2.1.1",
            //       new TreeNode() ParentID = 6,NodeID = 9,NodeName = "SubSection2.1.2",
            //        new TreeNode() ParentID = 2,NodeID = 10,NodeName = "Section2.2",
            //         new TreeNode() ParentID = 3,NodeID = 11,NodeName = "Section3.2",
            //;
            //nodes = getNodes(0,nodes);


            //方法2 
            nodesCollection = new ObservableCollection<TreeNode>()
            
               new TreeNode()
               
                   NodeName = "中国人",
                   ChildNodes = new ObservableCollection<TreeNode>()
                   
                       new TreeNode() NodeName = "李嘉诚",
                       new TreeNode()
                       
                           NodeName = "王健林",
                           ChildNodes = new ObservableCollection<TreeNode>()
                           
                               new TreeNode() NodeName = "68岁",
                               new TreeNode() NodeName = "一个儿子",
                           
                       ,
                   
               ,
                new TreeNode()
               
                   NodeName = "外国人",
                   ChildNodes = new ObservableCollection<TreeNode>()
                   
                       new TreeNode()
                       
                           NodeName = "马斯克",
                           ChildNodes = new ObservableCollection<TreeNode>()
                           
                               new TreeNode() NodeName = "51岁",
                               new TreeNode() NodeName = "10个老婆",
                           
                       ,
                   
               
            ;
        
        public List<EmployeeDepartment> EmployeeDepartments  get; set; 


        public List<TreeNode> nodes  get; set; 
        public ObservableCollection<TreeNode> nodesCollection  get; set; 
        //private List<TreeNode> getNodes(int parentID, List<TreeNode> nodes)
        //
        //    List<TreeNode> mainNodes = nodes.Where(x => x.ParentID == parentID).ToList();
        //    List<TreeNode> otherNodes = nodes.Where(x => x.ParentID != parentID).ToList();
        //    foreach (TreeNode node in mainNodes)
        //        node.ChildNodes = getNodes(node.NodeID, otherNodes);
        //    return mainNodes;
        //
        public void CheckBox_Click(object sender, RoutedEventArgs e)
        
            CheckBox checkBox;
            if (sender is CheckBox)
            
                checkBox = sender as CheckBox;
            
            else
            
                return;
            


            //SetIsChecked(nodesCollection);
            foreach (var childNode in nodesCollection)
            
                //SetIsChecked(childNode, checkBox.IsChecked);
                SetIsChecked(childNode);
            
        


        //public void SetIsChecked(ObservableCollection<TreeNode> childNodes)
        //
        //    foreach (var childNode in childNodes)
        //    
        //        if(!childNode.IsChecked)
        //        
        //            foreach (var child in childNode.ChildNodes)
        //            
        //                child.IsChecked = false;
        //                SetIsChecked(child.ChildNodes);
        //            
        //        
        //        else
        //        
        //            SetIsChecked(childNode.ChildNodes);
        //        
        //    
        //


        public void SetIsChecked(TreeNode treeNode)
        
            foreach (var child in treeNode.ChildNodes)
            
                if (!treeNode.IsChecked)
                
                    child.IsChecked = false;
                
                SetIsChecked(child);
            
        


    


    public static class Departments
    
        public static List<EmployeeDepartment> GetDepartments()
        
            List<EmployeeDepartment> departments = new List<EmployeeDepartment>();
            departments.Add(new EmployeeDepartment("Management", new Employee[] 
                new Employee(0, "Gregory S. Price")
            ));
            departments.Add(new EmployeeDepartment("Marketing", new Employee[] 
                new Employee(1, "Irma R. Marshall"),
                new Employee(2, "Brian C. Cowling"),
                new Employee(3, "Thomas C. Dawson"),
                new Employee(4, "Bryan R. Henderson"),
            ));
            departments.Add(new EmployeeDepartment("Operations", new Employee[] 
                new Employee(5, "John C. Powell"),
                new Employee(6, "Harold S. Brandes"),
                new Employee(7, "Jan K. Sisk"),
                new Employee(8, "Sidney L. Holder"),
            ));
            departments.Add(new EmployeeDepartment("Production", new Employee[] 
                new Employee(9, "Christian P. Laclair"),
                new Employee(10, "James L. Kelsey"),
                new Employee(11, "Howard M. Carpenter"),
                new Employee(12, "Jennifer T. Tapia"),
            ));
            departments.Add(new EmployeeDepartment("Finance", new Employee[] 
                new Employee(13, "Karen J. Kelly"),
                new Employee(14, "Judith P. Underhill"),
                new Employee(15, "Russell E. Belton"),
            ));
            return departments;
        
    


    public class Employee
    
        public Employee(int id, string name)
        
            ID = id;
            Name = name;
        
        public int ID  get; set; 
        public string Name  get; set; 
    
    public class EmployeeDepartment
    
        public string Name  get; set; 
        public ObservableCollection<Employee> Employees  get; 


        public EmployeeDepartment(string name, IEnumerable<Employee> employees)
        
            Name = name;
            Employees = new ObservableCollection<Employee>(employees);
        
    


    [AddINotifyPropertyChangedInterface]
    public class TreeNode
    
        //public int NodeID  get; set; 
        //public int ParentID  get; set; 
        public string NodeName  get; set; 
        public bool IsChecked  get; set; 
        public ObservableCollection<TreeNode> ChildNodes  get; set; 
        public TreeNode()
        
            IsChecked = true;
            ChildNodes = new ObservableCollection<TreeNode>();
        
    

通过SetIsChecked方法实现了主节点取消勾选后,子节点也跟着去勾选,要勾选子节点,也先得选中主节点.

源码下载

  链接:https://pan.baidu.com/s/1ty500tUFPNGtfnJorqaZ7A 

提取码:6666

以上是关于delphi中treeview的用法的主要内容,如果未能解决你的问题,请参考以下文章

bootstrap treevie只展开一个节点,关闭其他节点

TreeView而不是WebView?

Treeview 丢失焦点后依然高亮 SelectedNode

WPF C# TreeView 获取所选项目的文本

delphi编程treeview,memo

DELPHI中treeview和DBgird的结合使用?