I have a Delphi Pop-Up menu that has three options: Delete Customer, Delete Order(s), and Delete Item.
What I want to do is to be able to display a pop-up menu with Delete Customer and Delete Order(s),
only
if
the Node is Level 0. But when the Selected Node is Level 1, then I only want the Delete Item option
to pop-up. Do you enable or disable the options? Here is a piece of my source: Thanks!!!
Let's start by summarizing a few things, next we'll analyze the problem and its solution
in words, and finally we try to translate this into Delphi code.
A customer can have order(s), and an order can have items. To represent this, we
need 3 levels of nodes: 0 for customers, 1 for orders, 2 for items.The popupmenu has
3 menu-items: "Delete
Customer", "Delete Order(s)", "Delete Item(s)". We set the treeview's property "Popupmenu" to
the name of the popupmenu, in order to call the popupmenu when the treeview receives
a right click; this can be done in the Object Inspector or in the OnCreate event of
the form.
During runtime, we enable / disable the items of the popupmenu, according to the following
rules:
1. If no node is selected, disable all the popupmenu-items.
2. If a level 0 node is selected:
- enable "Delete Customer"
- if the customer has at least one order, enable "Delete Order(s)"
- disable "Delete Item(s)"
3. If a level 1 node is selected:
- enable "Delete Order(s)"
- if the order has at least one item, enable "Delete Item(s)"
- disable "Delete Customer"
4. If a level 2 node is selected:
- enable "Delete Item(s)"
- disable "Delete Customer"
- disable "Delete Order(s)"
By dynamically changing the menu-items' captions, we can show the customer if just
the selected node will be deleted, or if also its child-nodes will be deleted. Let's
change the menu-items' captions as follows:
Menu-item 0:
always "Delete Customer", because you only delete one customer at a time.
Menu-item 1:
if a level 0 node is selected with more than 1 child node: "Delete all Orders
of this Customer";
else: "Delete Order".
Menu-item 2:
if a level 1 node is selected with more than 1 child node: "Delete all Items
of this Order";
else: "Delete Item".
You can set the menu-items in the event handler for OnPopup. To keep the code a bit
shorter, I renamed the popupmenu to "PM".
procedure TForm1.PMPopup(Sender: TObject);
const
DeleteOne: array[0..2] of string = ('Customer', 'Order', 'Item');
DeleteMore: array[1..2] of string =
('all Orders of Customer', 'all Items of Order');
var
Node: TTreeNode;
i: integer;
begin
Node := Treeview1.Selected;
for i := 0 to 2 do
with PM.Items[i] do begin
Enabled := (i = Node.Level) or
(i = Node.Level + 1) and (Node.Count > 0);
if (i = Node.Level + 1) and (Node.Count > 1) then
Caption := 'Delete ' + DeleteMore[i]
else
Caption := 'Delete ' + DeleteOne[i];
end;
end;
Next, create 3 OnClick event handlers for the items of PopupMenu 1. Or write one
common OnClick handler, and use the "MenuIndex" property, for example:
procedure TForm1.PMItemClick(Sender: TObject);
begin
case (Sender as TMenuItem).MenuIndex of
0: begin
Delete_All_Orders_Of_Selected_Customer;
Delete_Selected_Customer;
end;
1: if Treeview1.Selected.Level = 0 then
Delete_All_Orders_Of_Selected_Customer
else
Delete_Selected_Order;
2: if Treeview1.Selected.Level = 1 then
Delete_All_Items_Of_Selected_Order
else
Delete_Selected_Item;
end;
end;