使用TreeView作导航,想法是每点击一个TreeNode就会弹出相应的子窗体。但是遇到了以下问题:如果弹出窗体的代码写在OnChange事件里面,发现当窗体被关闭后,再次点击选中节点,不会触发OnChange事件,失败;如果使用OnClick事件,发现点击TreeView的任何地方(哪怕没有点击任何节点),都会弹出被选中那个节点对应的窗体,失败;于是改在OnMouseDown/Up事件中获取鼠标的坐标X,Y,然后再OnClick事件中使用GetNodeAt方法获得被点中的节点,情况稍有改观——但是——点击节点左侧的展开符号[+]时,会以一定概率弹出被展开的第一个子节点对应的窗体,失败中的失败……那位高人能给一个比较完美的解决办法?残念中……

解决方案 »

  1.   

    可以写在OnClick中,在加上一条if语句,只有在点中这个node时才触发事件
      

  2.   

    procedure TForm1.TreeView1Click(Sender: TObject);
    var
      pt: TPoint;
      tNode: TTreeNode;
    begin
      GetCursorPos(pt);
      pt := TreeView1.ScreenToClient(pt);
      tNode := TreeView1.GetNodeAt(pt.X, pt.Y);
      if tNode <> nil then begin
        if tNode <> TreeView1.Selected then Exit;
        if not PtInRect(tNode.DisplayRect(True), pt) then Exit;
        ShowMessage(tNode.Text);
        // 显示相应窗体
      end;
    end;
      

  3.   

    procedure TForm1.TreeView1MouseDown(Sender: TObject;
      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    var
      h: THitTests;
      n: TTreeNode;
    begin
      h:=tvNavigater.GetHitTestInfoAt(X,Y);  if (htOnItem in h) or (htOnIcon in h) then
        begin
          n:=tvNavigater.GetNodeAt(X,Y);
          if not(n=nil) then
            begin
              //显示窗体
            end;
        end;
    end;