2010-02-26 3 views
4

У меня есть всплывающее меню, в котором есть несколько элементов.Элементы динамического меню Delphi

 
Option 1 
- Sub1 
- Sub2 
Option 2 
- Sub1 
- Sub2 
Option 3 
- Sub1 
- Sub2 

Я хочу, чтобы иметь возможность добавить Sub подменю в Option 3 sub2 так он будет выглядеть следующим образом:

 
Option 1 
- Sub1 
- Sub2 
Option 2 
- Sub1 
- Sub2 
Option 3 
- Sub1 
- Sub2 
    - Dynamic Item1 
    - Dynamic Item2 
    - Dynamic Item3 

Я пытался работать со следующим кодом, чтобы понять это , Я могу сделать это «ЕСЛИ», опция меню еще не существует (вариант 3), но я не могу этого сделать, если опция 3 уже существует (она создает дублирующее меню)

Как мне это сделать?

Спасибо


unit Unit2; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, Menus, StdCtrls; 

type 
    TForm2 = class(TForm) 
    popMenu: TPopupMenu; 
    gbDynamic: TGroupBox; 
    gbMain: TGroupBox; 
    popDynamic: TPopupMenu; 
    Option11: TMenuItem; 
    Option21: TMenuItem; 
    Option31: TMenuItem; 
    Sub11: TMenuItem; 
    Sub21: TMenuItem; 
    Item11: TMenuItem; 
    Item21: TMenuItem; 
    Item31: TMenuItem; 
    Item41: TMenuItem; 
    Sub12: TMenuItem; 
    Sub22: TMenuItem; 
    Sub13: TMenuItem; 
    Sub23: TMenuItem; 
    Option12: TMenuItem; 
    Sub24: TMenuItem; 
    Sub14: TMenuItem; 
    Option22: TMenuItem; 
    Sub25: TMenuItem; 
    Sub15: TMenuItem; 
    Option32: TMenuItem; 
    Sub26: TMenuItem; 
    Sub16: TMenuItem; 
    Label1: TLabel; 
    procedure FormCreate(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    Procedure PopupItemClick (Sender : TObject); 
    end; 

var 
    Form2: TForm2; 
    stlist: TStrings; 

implementation 

{$R *.dfm} 

procedure TForm2.FormCreate(Sender: TObject); 
Var 
    menuItem,SubItem : TMenuItem; 
    I, N : Integer; 
    s : String; 

begin 
//This will be a downloaded list from a server. 
    stlist := TStringList.Create; 
    stlist.Add ('Item 1'); 
    stlist.Add ('Item 2'); 
    stlist.Add ('Item 3'); 

    SubItem := TMenuItem.Create(popDynamic); 
    SubItem.Caption := 'Option 3'; 
    popDynamic.Items.Add(SubItem); 

    MenuItem := TMenuItem.Create(popDynamic); 
    MenuItem.Caption := 'Sub 1'; 
    SubItem.Add(MenuItem); 
    //This would work if Option 3 menu item was not aleady a menu item. 

     For I := 0 To stlist.Count - 1 Do 
      Begin 
      SubItem := TMenuItem.Create (popDynamic); 
      SubItem.Caption := stlist [i]; 
      SubItem.OnClick := PopupItemClick; 
      //assign it a custom integer value.. 
      SubItem.Tag := i; 
      MenuItem.Add(SubItem); 
      End; 
end; 
Procedure TForm2.PopupItemClick (Sender : TObject); 
Var 
    menuItem : TMenuItem; 
Begin 
    menuItem := TMenuItem (sender); 
    label1.caption := stlist.Strings [menuItem.Tag]; 
End; 
end. 

Форма:

 
object Form2: TForm2 
    Left = 0 
    Top = 0 
    Caption = 'Form2' 
    ClientHeight = 247 
    ClientWidth = 480 
    Color = clBtnFace 
    Font.Charset = DEFAULT_CHARSET 
    Font.Color = clWindowText 
    Font.Height = -11 
    Font.Name = 'Tahoma' 
    Font.Style = [] 
    OldCreateOrder = False 
    OnCreate = FormCreate 
    PixelsPerInch = 96 
    TextHeight = 13 
    object gbDynamic: TGroupBox 
    Left = 0 
    Top = 0 
    Width = 217 
    Height = 247 
    Align = alLeft 
    Caption = 'Dynamic' 
    PopupMenu = popDynamic 
    TabOrder = 0 
    object Label1: TLabel 
     Left = 48 
     Top = 32 
     Width = 31 
     Height = 13 
     Caption = 'Label1' 
    end 
    end 
    object gbMain: TGroupBox 
    Left = 217 
    Top = 0 
    Width = 263 
    Height = 247 
    Align = alClient 
    Caption = 'What I Want Dynamically Created' 
    PopupMenu = popMenu 
    TabOrder = 1 
    ExplicitLeft = 336 
    ExplicitTop = 72 
    ExplicitWidth = 185 
    ExplicitHeight = 105 
    end 
    object popDynamic: TPopupMenu 
    Left = 136 
    Top = 96 
    object Option12: TMenuItem 
     Caption = 'Option 1' 
     object Sub14: TMenuItem 
     Caption = 'Sub 1' 
     end 
     object Sub24: TMenuItem 
     Caption = 'Sub 2' 
     end 
    end 
    object Option22: TMenuItem 
     Caption = 'Option 2' 
     object Sub15: TMenuItem 
     Caption = 'Sub 1' 
     end 
     object Sub25: TMenuItem 
     Caption = 'Sub 2' 
     end 
    end 
    object Option32: TMenuItem 
     Caption = 'Option 3' 
     object Sub16: TMenuItem 
     Caption = 'Sub 1' 
     end 
     object Sub26: TMenuItem 
     Caption = 'Sub 2' 
     end 
    end 
    end 
    object popMenu: TPopupMenu 
    Left = 256 
    Top = 112 
    object Option11: TMenuItem 
     Caption = 'Option 1' 
     object Sub13: TMenuItem 
     Caption = 'Sub 1' 
     end 
     object Sub23: TMenuItem 
     Caption = 'Sub 2' 
     end 
    end 
    object Option21: TMenuItem 
     Caption = 'Option 2' 
     object Sub12: TMenuItem 
     Caption = 'Sub 1' 
     end 
     object Sub22: TMenuItem 
     Caption = 'Sub 2' 
     end 
    end 
    object Option31: TMenuItem 
     Caption = 'Option 3' 
     object Sub11: TMenuItem 
     Caption = 'Sub 1' 
     object Item11: TMenuItem 
      Caption = 'Item 1' 
     end 
     object Item21: TMenuItem 
      Caption = 'Item 2' 
     end 
     object Item31: TMenuItem 
      Caption = 'Item 3' 
     end 
     object Item41: TMenuItem 
      Caption = 'Item 4' 
     end 
     end 
     object Sub21: TMenuItem 
     Caption = 'Sub 2' 
     end 
    end 
    end 
end 

ответ

3

Самый простой способ сделать это, чтобы дать OPTION3 имя, а затем проверить его в цикле:

SubItem := nil; 
for i := 0 to popdynamic.Items.Count-1 do 
    if SameText(popdynamic.Items[i].Name, 'mnuOption3') then 
    SubItem := popdynamic.Items[i]; 

if SubItem = nil then 
    begin 
    SubItem := TMenuItem.Create(popDynamic); 
    SubItem.Caption := 'Option 3'; 
    Subitem.Name := 'mnuOption3'; 
    popDynamic.Items.Add(SubItem); 
    end; 

Таким образом, вы не создадите новый подэлемент, если он уже существует.

+0

Я только что обновил код – Brad

+0

Спасибо за код примера! – Brad

1

Все, что вам нужно сделать для создания нового подменю, - это ссылка на существующий пункт меню - если он один и тот же каждый раз, просто обратитесь к объекту напрямую, в противном случае найдите его как-то - и затем вызовите Add on with with TMenuItem, который вы хотите добавить. Я использую что-то подобное в одном из моих приложений для рекурсивного создания меню из файла XML.

Это должно быть очень сжатой версией того, что я делаю.

procedure TMainForm.AddMenuItems(XMLNode: IXMLDOMNode; Parent: TMenuItem); 
var 
    node: IXMLNode; 
    item: TMenuItem; 
begin 
    for i := 0 to XMLNode.childNodes.length - 1 do begin 
    node := XMLNode.childNodes.item[i]; 
    item := NewItem(node.attributes.getNamedItem('name').nodeValue, 0, false, true, nil, 0, ''); 
    if node.nodeName = 'group' then begin 
     Parent.Add(item); 
     AddMenuItems(node, item); 
    end else begin 
     //You probably want to add a Tag to your items so you can tell them apart. 
     item.OnClick := DynamicItemClick; 
     Parent.Add(item); 
    end; 
    end; 
end; 

procedure TMainForm.LoadData; 
var 
    XMLNode: IXMLNode; 
    //... 
begin 
    //Clear old dynamic items 
    while Set1.Count > 0 do 
    Set1.Items[0].Free; 
    //Open XML file, find right XMLNode... 
    AddMenuItems(XMLNode.firstChild, Set1, ''); 
end; 

... где Set1 - это пункт меню, для которого я создаю пункты меню. В вашем случае, я предполагаю, что это будет Sub26 (и Sub23 для одного во всплывающем меню). Просто используйте этот базовый подход, заменив материал XML тем, что вам нужно, чтобы прочитать ваш файл.

Смежные вопросы