问题描述:
在 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,如需转载请自行联系原作者