4 Stimmen

Dynamische Menüpunkte in Delphi

Ich habe ein Popup-Menü, das einige Einträge enthält.

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

Ich möchte in der Lage sein, ein Untermenü zu Option 3 sub2 hinzuzufügen, so dass es wie folgt aussehen würde:

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

Ich habe versucht, mit dem folgenden Code zu arbeiten, um es herauszufinden, kann ich es tun, "WENN" die Menüoption nicht bereits vorhanden ist (Option 3), aber ich kann es nicht tun, wenn Option 3 bereits vorhanden ist (Es erstellt eine doppelte Menüoption)

Wie würde ich das machen?

Dankeschön

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.

Form:

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

3voto

skamradt Punkte 15128

Am einfachsten ist es, der Option3 einen Namen zu geben und sie dann in einer Schleife zu suchen:

 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;

Auf diese Weise erstellen Sie keinen neuen Unterpunkt, wenn er bereits existiert.

1voto

Michael Madsen Punkte 52883

Alles, was Sie tun müssen, um ein neues Untermenü zu erstellen, ist der Verweis auf den vorhandenen Menüpunkt - wenn es immer derselbe ist, verweisen Sie einfach direkt auf das Objekt, andernfalls müssen Sie es irgendwie finden - und rufen dann Add mit dem TMenuItem auf, das Sie hinzufügen möchten. Ich verwende etwas Ähnliches in einer meiner Anwendungen, um rekursiv ein Menü aus einer XML-Datei zu erstellen.

Dies sollte als eine sehr komprimierte Version dessen dienen, was ich tue.

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;

...wobei Set1 der Menüpunkt ist, für den ich Menüpunkte erstellen möchte. In Ihrem Fall wäre das wohl Sub26 (und Sub23 für den Eintrag im Popup-Menü). Verwenden Sie einfach diesen grundlegenden Ansatz und ersetzen Sie das XML-Zeug durch das, was Sie zum Lesen Ihrer Datei benötigen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X