Posted by Jennifer on June 18, 2001
Hello all! Ok, here is what's given: I have a parent node and child node(s) which looks like this:
+ 1 Joe
|
|___1 Monitor
|
|___4 Floppy
which means that Joe(CustomerID = 1) ordered 1 monitor and 4 floppy drives.
I have a Table called Orders with Fields (in order): OrderNumber, CustomerID, ItemNumber, MyDate Now, problem here is how would I be able to delete an item (the monitor or floppy) from the Orders Table when the user clicks on the DeleteItem Pop-up Menu? What I mean is how would I extract the OrderNumber for that particular selected item or child node, so that I can delete it from the Table? What I need is a function... Thanks a lot!!! J.D.
Re: webmaster Guido on June 27
You could either add OrderNumber to each item-node, or reorganize the treeview and
have an extra level for the orders.
1. If you stick to the 2 level treeview, the easiest method is: add OrderNumber to
the text of each item-node at the moment that you create the node. For example:
- 1 Joe
|__ 1 Monitor - Order: 1234
|__ 4 Floppy - Order: 1234
To set the text of an item node, if OrderNumber is an integer:
Node.Text := ...; // what you do now to set the text
Node.Text := Node.Text + ' - Order: ' + IntToStr(OrderNumber);
Or, if OrderNumber is a string, we'd better call it OrderID in that case:
Node.Text := ...; // what you do now to set the text
Node.Text := Node.Text + ' - Order: ' + OrderID;
To extract OrderID from the selected item-node:
OrderID := IDFromNodeText(Treeview1.Selected.Text);
The function:
function TForm1.IDFromNodeText(S: string): string;
var
P: integer;
begin
P := LastDelimiter(' ', ItemText); // position of last space
// Extract ID
Result := copy(S, P + 1, Length(S) - P);
end;
2. Better would be to work with three levels instead of two, and to have separate
tables for orders and order-items, because in the first example you can have only one
order per customer. Also note that I put CustomerID in the last part of the customer-node
text.
Joe 1
|_ Order 285
| |_ 1 Monitor
| |_ 4 Floppy
|
|_ Order 286
|_ 2 Keyboard
|_ 2 Mouse
When an item-node is selected, you can extract OrderID from the order-node, which
is the parent of the selected item-node:
OrderID := IDFromNodeText(Treeview1.Selected.Parent.Text);
The code for the function itself is the same as in the first example. If your treeview
is organized in this way, you can use the same function to extract all ID's, only the
parameter will change.
If an item-node is selected:
OrderID := IDFromNodeText(Treeview1.Selected.Parent.Text);
CustomerID := IDFromNodeText(Treeview1.Selected.Parent.Parent.Text);
If an order-node is selected:
OrderID := IDFromNodeText(Treeview1.Selected.Text);
CustomerID := IDFromNodeText(Treeview1.Selected.Parent.Text);
If a customer-node is selected:
CustomerID := IDFromNodeText(Treeview1.Selected.Text);
There are other ways to add ID's in an invisible way to the nodes, such as using
the node's Data property to store a pointer, or even maintain a list (in memory, such
as
a TStringlist) with details of each node.
But I think that it's a lot easier for the user when she/he actually sees the ID's of
customers, and orders.
And of course, you can easily extend this code to item-ID's.
Re: Pavement on June 27, 2001
I dont know the answer to your question, but i was working with Treeviews a little
while back and didn't recieve any help, it seems nobody knows!... so all i can do is
post my source code.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
FormEx, ComCtrls, StdCtrls, TFlatTabControlUnit, TFlatComboBoxUnit,
Buttons, Menus;
type
TMainForm = class(TForm)
TreeView: TTreeView;
mView: TMemo;
BtnDel: TButton;
lblName: TLabel;
BtnPAdd: TBitBtn;
MainMenu1: TMainMenu;
procedure OnNodeChange(Sender: TObject; Node: TTreeNode);
procedure DelSelectedNode(Sender: TObject);
procedure AddNew(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
type
PData = ^TData;
TData = record
Name : string;
Comments : string;
end;
var
MainForm: TMainForm;
TreeStream, DataStream: TFileStream;
implementation
uses unit2;
{$R *.DFM}
procedure TMainForm.OnNodeChange(Sender: TObject; Node: TTreeNode);
begin
if treeview.selected.level <> 0 then
begin
mView.Text := PData(TreeView.Selected.Data)^.Comments;
lblName.Caption := PData(TreeView.Selected.Data)^.Name;
end
end;
procedure TMainForm.DelSelectedNode(Sender: TObject);
begin
if treeview.selected.level <> 0 then
treeview.selected.free;
end;
procedure TMainForm.AddNew(Sender: TObject);
var
DataPtr: PData;
begin
AddNode := TAddNode.Create(Self);
AddNode.ShowModal;
AddNode.Free;
if status = 1 then
begin
New(DataPtr);
DataPtr^.Name := NewName;
DataPtr^.Comments := NewComments;
with treeview do
if selected.level <> 0 then
selected := selected.parent;
treeview.items.AddchildObjectfirst(treeview.selected, NewName, DataPtr);
treeview.fullexpand;
end
else
begin
mView.Text := '';
lblName.Caption := '';
end;
end;
procedure TMainForm.FormCreate(Sender: TObject);
var
F:TFileStream;
begin
F:=TFileStream.Create('TreeView.txt',fmOpenRead or fmShareDenyWrite);
F.ReadComponent(TreeView);
F.Free;
end;
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
var
F: TFileStream;
begin
F:=TFileStream.Create('TreeView.txt',fmCreate or fmShareCompat);
F.WriteComponent(TreeView);
F.Free;
end;
end.
----------------------------------
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, TFlatComboBoxUnit;
type
TAddNode = class(TForm)
BtnOk: TBitBtn;
BtnCan: TBitBtn;
mComments: TMemo;
edName: TEdit;
FlatComboBox1: TFlatComboBox;
procedure BtnOkClick(Sender: TObject);
procedure BtnCanClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
AddNode: TAddNode;
NewName, NewComments: string;
Status: integer;
implementation
uses Unit1;
{$R *.DFM}
procedure TAddNode.BtnOkClick(Sender: TObject);
begin
Status := 1;
If (mComments <> Nil) and (edName <> Nil) then
begin
NewName := edName.text;
NewComments := mComments.text;
AddNode.Close;
end
else
begin
NewName := 'New';
NewComments := 'No Comments';
AddNode.Close;
end
end;
procedure TAddNode.BtnCanClick(Sender: TObject);
begin
AddNode.Close;
Status := 2
end;
end.
|