我从 TTreeView 继承了一个自定义控件,需要捕获 TreeView 节点的“添加、删除、修改、移动”的事件,从而自动对数据库记录进行修改,请问如何捕获这样的事件呢?或者有没有其它思路使对 TreeView 节点的修改可以关联到 数据库记录 的修改?(我想使用 TFieldDatalink 将 TreeView 与数据库连接)

解决方案 »

  1.   

    看来没办法实现了,我想还是重写整个 TCustomTreeView 好了,使用自定义的 TTreeNode 来触发事件。
      

  2.   

    谢谢 youthon 热心回复,我希望 TMyTreeView 可以禁用 TTreeView 原始的添加删除节点功能,否则,如果用户通过 TTreeView 自身的添加删除节点功能,那么就失去和数据库的关联了。我想,还是需要重写整个 TCustomTreeView,改用自定义的 TTreeNode 类。不知道还有没有简单的方法,设计一个 TDBTreeView。
      

  3.   

    谢谢 youthon 热心回复,我希望 TMyTreeView 可以禁用 TTreeView 原始的添加删除节点功能,否则,如果用户通过 TTreeView 自身的添加删除节点功能,那么就失去和数据库的关联了。我想,还是需要重写整个 TCustomTreeView,改用自定义的 TTreeNode 类。不知道还有没有简单的方法,设计一个 TDBTreeView。
      

  4.   

    TCustomTreeView的方法都是protected的,子类都可以重写的
      

  5.   

    可是下面这些都是私有的,而 TTreeNode 都有自己的“添加、删除”节点的方法。不修改 TTreeNode 就无法控制它的节点操作。FDragNode: TTreeNode;
    FRClickNode: TTreeNode;
    FTreeNodes: TTreeNodes;
    procedure SelectNode(Node: TTreeNode);
      

  6.   

    今天看了一下,确实用继承的方式比较困难
    用treeview的事件OnDeletion、OnAddition可以实现对添加和删除节点的控制,编辑应该也可以
    移动貌似不行,不过如何能移动节点呢?
      

  7.   

    你所说的移动是指什么操作? NODE  的位置变化了?还是其他
      

  8.   


    节点移动是指:TTreeView.Selected.MoveTo也就是 TTreeNode.MoveTo
      

  9.   

    TTreeNode.MoveTo方法也会触发add和delete事件
      

  10.   

    这是我测试 TTreeView 所有事件的代码,发现在移动节点的时候不会激发 Add 和 Delete 事件。unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ComCtrls, StdCtrls;type
      TForm1 = class(TForm)
        tv1: TTreeView;
        btn1: TButton;
        mmo1: TMemo;
        procedure FormCreate(Sender: TObject);
        procedure tv1Addition(Sender: TObject; Node: TTreeNode);
        procedure tv1Deletion(Sender: TObject; Node: TTreeNode);
        procedure tv1Change(Sender: TObject; Node: TTreeNode);
        procedure tv1AdvancedCustomDraw(Sender: TCustomTreeView; const ARect: TRect;
          Stage: TCustomDrawStage; var DefaultDraw: Boolean);
        procedure tv1AdvancedCustomDrawItem(Sender: TCustomTreeView;
          Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage;
          var PaintImages, DefaultDraw: Boolean);
        procedure tv1CancelEdit(Sender: TObject; Node: TTreeNode);
        procedure tv1Changing(Sender: TObject; Node: TTreeNode;
          var AllowChange: Boolean);
        procedure tv1Click(Sender: TObject);
        procedure tv1Collapsed(Sender: TObject; Node: TTreeNode);
        procedure tv1Collapsing(Sender: TObject; Node: TTreeNode;
          var AllowCollapse: Boolean);
        procedure tv1Compare(Sender: TObject; Node1, Node2: TTreeNode;
          Data: Integer; var Compare: Integer);
        procedure tv1ContextPopup(Sender: TObject; MousePos: TPoint;
          var Handled: Boolean);
        procedure tv1CreateNodeClass(Sender: TCustomTreeView;
          var NodeClass: TTreeNodeClass);
        procedure tv1CustomDraw(Sender: TCustomTreeView; const ARect: TRect;
          var DefaultDraw: Boolean);
        procedure tv1CustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode;
          State: TCustomDrawState; var DefaultDraw: Boolean);
        procedure tv1DblClick(Sender: TObject);
        procedure tv1DragDrop(Sender, Source: TObject; X, Y: Integer);
        procedure tv1DragOver(Sender, Source: TObject; X, Y: Integer;
          State: TDragState; var Accept: Boolean);
        procedure tv1Edited(Sender: TObject; Node: TTreeNode; var S: string);
        procedure tv1Editing(Sender: TObject; Node: TTreeNode;
          var AllowEdit: Boolean);
        procedure tv1EndDock(Sender, Target: TObject; X, Y: Integer);
        procedure tv1EndDrag(Sender, Target: TObject; X, Y: Integer);
        procedure tv1Enter(Sender: TObject);
        procedure tv1Exit(Sender: TObject);
        procedure tv1Expanded(Sender: TObject; Node: TTreeNode);
        procedure tv1Expanding(Sender: TObject; Node: TTreeNode;
          var AllowExpansion: Boolean);
        procedure tv1Gesture(Sender: TObject; const EventInfo: TGestureEventInfo;
          var Handled: Boolean);
        procedure tv1GetSelectedIndex(Sender: TObject; Node: TTreeNode);
        procedure tv1GetImageIndex(Sender: TObject; Node: TTreeNode);
        procedure tv1Hint(Sender: TObject; const Node: TTreeNode; var Hint: string);
        procedure tv1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
        procedure tv1KeyPress(Sender: TObject; var Key: Char);
        procedure tv1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
        procedure tv1MouseActivate(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y, HitTest: Integer;
          var MouseActivate: TMouseActivate);
        procedure tv1MouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure tv1MouseEnter(Sender: TObject);
        procedure tv1MouseLeave(Sender: TObject);
        procedure tv1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
        procedure tv1MouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure tv1StartDock(Sender: TObject; var DragObject: TDragDockObject);
        procedure tv1StartDrag(Sender: TObject; var DragObject: TDragObject);
        procedure btn1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      bDrawLine: Boolean;
      iEventGroupIndex: Integer;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
    begin
      mmo1.Clear;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      tv1.Items.Add(nil, '111');
      tv1.Items.Add(nil, '222');
      tv1.Items.Add(nil, '333');
      tv1.Items.Add(nil, '444');
      tv1.Items.Add(nil, '555');
      bDrawLine := True;
      iEventGroupIndex := 0;
    end;procedure TForm1.tv1Addition(Sender: TObject; Node: TTreeNode);
    begin
      mmo1.Lines.Add('OnAddition');
      bDrawLine := True;
    end;procedure TForm1.tv1AdvancedCustomDraw(Sender: TCustomTreeView;
      const ARect: TRect; Stage: TCustomDrawStage; var DefaultDraw: Boolean);
    begin
    //  mmo1.Lines.Add('OnAdvancedCustomDraw');
    //  bDrawLine := True;
    end;procedure TForm1.tv1AdvancedCustomDrawItem(Sender: TCustomTreeView;
      Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage;
      var PaintImages, DefaultDraw: Boolean);
    begin
    //  mmo1.Lines.Add('OnAdvancedCustomDrawItem');
    //  bDrawLine := True;
    end;procedure TForm1.tv1CancelEdit(Sender: TObject; Node: TTreeNode);
    begin
      mmo1.Lines.Add('OnCancelEdit');
      bDrawLine := True;
    end;procedure TForm1.tv1Change(Sender: TObject; Node: TTreeNode);
    begin
    //  mmo1.Lines.Add('OnChange');
    //  bDrawLine := True;
    end;procedure TForm1.tv1Changing(Sender: TObject; Node: TTreeNode;
      var AllowChange: Boolean);
    begin
    //  mmo1.Lines.Add('OnChanging');
    //  bDrawLine := True;
    end;procedure TForm1.tv1Click(Sender: TObject);
    begin
    //  mmo1.Lines.Add('OnClick');
    //  bDrawLine := True;
    end;procedure TForm1.tv1Collapsed(Sender: TObject; Node: TTreeNode);
    begin
    //  mmo1.Lines.Add('OnCollapsed');
    //  bDrawLine := True;
    end;procedure TForm1.tv1Collapsing(Sender: TObject; Node: TTreeNode;
      var AllowCollapse: Boolean);
    begin
    //  mmo1.Lines.Add('OnCollapsing');
    //  bDrawLine := True;
    end;procedure TForm1.tv1Compare(Sender: TObject; Node1, Node2: TTreeNode;
      Data: Integer; var Compare: Integer);
    begin
      mmo1.Lines.Add('OnCompare');
      bDrawLine := True;
    end;procedure TForm1.tv1ContextPopup(Sender: TObject; MousePos: TPoint;
      var Handled: Boolean);
    begin
      mmo1.Lines.Add('OnContextPopup');
      bDrawLine := True;
    end;procedure TForm1.tv1CreateNodeClass(Sender: TCustomTreeView;
      var NodeClass: TTreeNodeClass);
    begin
      mmo1.Lines.Add('OnCreateNodeClass');
      bDrawLine := True;
    end;procedure TForm1.tv1CustomDraw(Sender: TCustomTreeView; const ARect: TRect;
      var DefaultDraw: Boolean);
    begin
    //  mmo1.Lines.Add('OnCustomDraw');
    //  bDrawLine := True;
    end;
      

  11.   

    代码太长,一个帖子发不完,下面是剩下的代码:procedure TForm1.tv1CustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode;
      State: TCustomDrawState; var DefaultDraw: Boolean);
    begin
    //  mmo1.Lines.Add('OnCustomDrawItem');
    //  bDrawLine := True;
    end;procedure TForm1.tv1DblClick(Sender: TObject);
    begin
      mmo1.Lines.Add('OnDblClick');
      bDrawLine := True;
    end;procedure TForm1.tv1Deletion(Sender: TObject; Node: TTreeNode);
    begin
      mmo1.Lines.Add('OnDeletion');
      bDrawLine := True;
    end;procedure TForm1.tv1DragDrop(Sender, Source: TObject; X, Y: Integer);
    begin
      mmo1.Lines.Add('OnDragDrop');
      bDrawLine := True;
    end;procedure TForm1.tv1DragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    begin
    //  mmo1.Lines.Add('OnDragOver');
    //  bDrawLine := True;
    end;procedure TForm1.tv1Edited(Sender: TObject; Node: TTreeNode; var S: string);
    begin
      mmo1.Lines.Add('OnEdited');
      bDrawLine := True;
    end;procedure TForm1.tv1Editing(Sender: TObject; Node: TTreeNode;
      var AllowEdit: Boolean);
    begin
      mmo1.Lines.Add('OnEditing');
      bDrawLine := True;
    end;procedure TForm1.tv1EndDock(Sender, Target: TObject; X, Y: Integer);
    begin
      mmo1.Lines.Add('OnEndDock');
      bDrawLine := True;
    end;procedure TForm1.tv1EndDrag(Sender, Target: TObject; X, Y: Integer);
    begin
      mmo1.Lines.Add('OnEndDrag');
      bDrawLine := True;
    end;procedure TForm1.tv1Enter(Sender: TObject);
    begin
    //  mmo1.Lines.Add('OnEnter');
    //  bDrawLine := True;
    end;procedure TForm1.tv1Exit(Sender: TObject);
    begin
    //  mmo1.Lines.Add('OnExit');
    //  bDrawLine := True;
    end;procedure TForm1.tv1Expanded(Sender: TObject; Node: TTreeNode);
    begin
    //  mmo1.Lines.Add('OnExpanded');
    //  bDrawLine := True;
    end;procedure TForm1.tv1Expanding(Sender: TObject; Node: TTreeNode;
      var AllowExpansion: Boolean);
    begin
    //  mmo1.Lines.Add('OnExpanding');
    //  bDrawLine := True;
    end;procedure TForm1.tv1Gesture(Sender: TObject; const EventInfo: TGestureEventInfo;
      var Handled: Boolean);
    begin
      mmo1.Lines.Add('OnGesture');
      bDrawLine := True;
    end;procedure TForm1.tv1GetImageIndex(Sender: TObject; Node: TTreeNode);
    begin
    //  mmo1.Lines.Add('OnGetImageIndex');
    //  bDrawLine := True;
    end;procedure TForm1.tv1GetSelectedIndex(Sender: TObject; Node: TTreeNode);
    begin
    //  mmo1.Lines.Add('OnGetSelectedIndex');
    //  bDrawLine := True;
    end;procedure TForm1.tv1Hint(Sender: TObject; const Node: TTreeNode;
      var Hint: string);
    begin
    //  mmo1.Lines.Add('OnHint');
    //  bDrawLine := True;
    end;procedure TForm1.tv1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    begin
    //  mmo1.Lines.Add('OnKeyDown');
    //  bDrawLine := True;
    end;procedure TForm1.tv1KeyPress(Sender: TObject; var Key: Char);
    begin
    //  mmo1.Lines.Add('OnKeyPress');
    //  bDrawLine := True;
    end;procedure TForm1.tv1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
    begin
    //  mmo1.Lines.Add('OnKeyUp');
    //  bDrawLine := True;
    end;procedure TForm1.tv1MouseActivate(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y, HitTest: Integer;
      var MouseActivate: TMouseActivate);
    begin
    //  mmo1.Lines.Add('OnMouseActivate');
    //  bDrawLine := True;
    end;procedure TForm1.tv1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
    //  mmo1.Lines.Add('OnMouseDown');
    //  bDrawLine := True;
    end;procedure TForm1.tv1MouseEnter(Sender: TObject);
    begin
    //  mmo1.Lines.Add('OnMouseEnter');
    //  bDrawLine := True;
    end;procedure TForm1.tv1MouseLeave(Sender: TObject);
    begin
    //  mmo1.Lines.Add('OnMouseLeave');
    //  bDrawLine := True;
    end;procedure TForm1.tv1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
    //  mmo1.Lines.Add('OnMouseMove');
      if bDrawLine then begin
        mmo1.Lines.Add(IntToStr(iEventGroupIndex) + '------------------------------');
        bDrawLine := False;
        Inc(iEventGroupIndex);
      end;
    end;procedure TForm1.tv1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
    //  mmo1.Lines.Add('OnMouseUp');
    //  bDrawLine := True;
    end;procedure TForm1.tv1StartDock(Sender: TObject; var DragObject: TDragDockObject);
    begin
      mmo1.Lines.Add('OnStartDock');
      bDrawLine := True;
    end;procedure TForm1.tv1StartDrag(Sender: TObject; var DragObject: TDragObject);
    begin
      mmo1.Lines.Add('OnStartDrag');
      bDrawLine := True;
    end;end.
      

  12.   

    忘了写 MoveTo 的代码了,我是用自定义的 TDragTreeView 通过拖拽来移动节点的,也是调用了 MoveTo 方法。
      

  13.   

    是啊,这个 TCustomTreeView 设计的欠妥。
      

  14.   

    在TreeView的OnChang事件中写代码,试试看。
      

  15.   


    TTreeView 中的 OnChange 捕捉的是节点的焦点被改变,也就是说,当你用鼠标选择另一个节点时,就会触发 OnChange 事件。MoveTo 不会触发 OnChange。