Delphi 中 Treeview 控件的节点(Node)焦点问题

问题描述:

    在 Delphi 中 Treeview 是一个常用的控件,可以非常有效的表现树形逻辑结构的信息。
    当鼠标右键点击选择了一个节点时,该节点的 selected 属性为 True,该节点成为 Treeview1.selected 节点。比如,在 Windows 的资源管理器中,如果我们点选了文件夹 A,那么文件夹 A 成为背景蓝色的矩形块,成为被选择的当前节点。
这个时候如果鼠标右键点击另一个节点(文件夹) B,在弹出菜单中点击属性,打开属性窗口,这时我们得到的其实是 B 文件夹的信息,并不是当前节点 A 的信息。
这其实是正常的,是业已约定成型的按键行为,也最符合人的思维习惯。在关闭属性窗口后,节点 A 还是保持为被选择的状态。
    但是在 Delphi 的 Treeview 中,在被选择节点和右键点击节点不是同一个节点的情况下,除非我们在右键菜单中打开一个 Message 对话框,打开别的窗口,是不能获得右键点击的节点的有关数据的。这个时候如果用 Treeview1.Selected.Text,得到的是焦点所在的、被选择(selected)节点的有关数据。这样在按键行为,不符合人们的操作习惯。

    比如以下代码,语句一得到了右键点击节点的文本值,而语句二打开的 Form2 中的文本框 Edit1,显示的是 Form1 上 Treeview1 的被选择节点的文本值。

    //Form1窗口的鼠标事件
    procedure TForm1.TreeView1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    var
      oNode: TTreeNode;
    begin
      //相应鼠标右键事件
      if Button=mbRight then
      begin
        oNode := TreeView1.GetNodeAt(X, Y);
        if oNode<>nil then
        begin
          ShowMessage(oNode.Text);  //语句一
          Form2.ShowModal;  //语句二
        end;
      end;
    end;

    //Form2窗口的激活事件
    procedure TOKBottomDlg.FormActivate(Sender: TObject);
    begin
      Edit1.Text := Form1.TreeView1.Selected.Text;
    end;

    原因分析:

    为什么信息对话框显示的是右键点击的节点的文本值,而在打开的 Form2 中得不到呢?原因是当打开 Form2 之前,Treeview1 上的节点焦点回到了被选择的节点上,在打开 Form2 后,这个时候再取 Form1.TreeView1.Selected.Text,已经不是右键点击的节点的数据了,而是焦点所在节点的数据。而 Form1.TreeView1.Node.Text; 也是一条语法错误的语句。

    解决办法:

    从 ShowMessage(oNode.Text); 语句得到启发,为了 Form2 取得右键点击节点的数据,必须在 Form2 打开之前首先获取这个值,通过参数传递给 Form2,就能避免焦点跳回带来的问题。

    这就需要定义一个可视的、能传递参数的对话框 Form,类似一下代码中的 TOKBottomDlg1。可以在 Delphi 的 IDE 环境下建立 TOKBottomDlg1 对话框,再定义
 GetValues 和 Execute 例程。

    unit myDialog;

    interface

    uses Windows, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls,
      Buttons, ExtCtrls, Dialogs;

    type
      TOKBottomDlg1 = class(TForm)
        BtnOK: TButton;
        BtnCancel: TButton;
        PromptLabel: TLabel;
      private
        { Private declarations }
        function Execute: Boolean;
      public
        { Public declarations }
        function GetValues(prompt: string): Boolean;
      end;

    var
      OKBottomDlg1: TOKBottomDlg1;

    implementation

    uses Main;

    {$R *.dfm}

    function TOKBottomDlg1.Execute: Boolean;
    begin
      Result := ShowModal=mrOk;
    end;

    function TOKBottomDlg1.GetValues(prompt: string): Boolean;
    begin
      PromptLabel.Caption := Form1.TreeView1.Selected.Text + ‘–’ + prompt;
      Result := OKBottomDlg1.Execute;
    end;

    end.

    在 Form1 的调用语句:

    unit Main;
    ……
    implementation
    {$R *.dfm}
    uses myDialog;
    ……

    procedure TForm1.TreeView1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      oNode: TTreeNode;
    begin
      if Button=mbRight then
      begin
        oNode := TreeView1.GetNodeAt(X, Y);
        if oNode<>nil then
        begin
          OKBottomDlg1.GetValues(oNode.Text);
        end;
      end;
    end;

    这样就很好的解决了问题。








本文转自网眼51CTO博客,原文链接:http://blog.51cto.com/itwatch/286539,如需转载请自行联系原作者

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值