2016-01-28 1 views
2

В моей системе главное меню полностью динамическое, оно построено из данных в базе данных.TMainMenu build пункт меню динамический

У меня есть конкретная ситуация, когда некоторые элементы меню необходимо собирать перед отображением.

Давайте предположим, что мое меню имеет следующие основные элементы:

Файлы - Клиент - Отчеты - О

Когда я нажимаю в Reports пункт меню должен собрать пункты, прежде чем они отображается.

Я проверил анализ кода в классах TMainMenu, TMenu и TMenuItem. К сожалению, я не нашел простого решения проблемы.

Существуют ли способы создания этих элементов перед их отображением?

+0

Возможно, вам придется заменить TMainMenu на другую реализацию. Как TActionMainMenuBar или меню из SpTBXLib. – Torbins

ответ

6

Есть трюк, который вы можете использовать. Вам необходимо добавить один манекен TMenuItem под Доклады и установить его Visible на False. Затем добавьте OnClick событие в Отчёт и введите свою населяющую логику. Прежде чем добавлять новые элементы, вы должны удалить существующие, но вы должны оставить свой фиктивный элемент неповрежденным.

Что-то вроде:

procedure TForm1.ReportItemClick(Sender: TObject); 
var 
    Item: TMenuItem; 
    I: Integer; 
begin 
    // Delete all items but first - dummy - one 
    for I := ReportItem.Count - 1 downto 1 do 
    ReportItem.Items[I].Free; 

    Item := TMenuItem.Create(ReportItem); 
    Item.Caption := 'abc'; 
// Item.OnClick := ... 
// or 
// Item.Action := ... 
    ReportItem.Add(Item); 

    Item := TMenuItem.Create(ReportItem); 
    Item.Caption := '123'; 
// Item.OnClick := ... 
// or 
// Item.Action := ... 
    ReportItem.Add(Item); 
end; 
+0

Вместо того, чтобы иметь невидимый элемент, вы также можете добавить эту логику на один уровень выше, поэтому нажмите клик на * Клиент *. Но ваше решение лучше, потому что оно не восстанавливает элемент, если вам нужно другое подменю, чем отчеты. – GolezTrol

+0

@GolezTrol Если я правильно понял, то Отчеты - это пункт главного меню, а не клиенты. Если это элемент в клиенте, ваша логика также может применяться. –

+0

Ах, я так не интерпретировал это, но, читая снова, я думаю, что ты прав. Ну, это все еще делает ваш ответ хорошим ответом. – GolezTrol

0

Позволяет Предположим, что у вас есть DS (TDataSet), как загрузить все ваши отчеты данных. И в тот момент, когда вы отбрасываете меню «Отчеты», вы можете вызвать UpdateMenuReport.

type 
TMenuArray = array of TMenuItem; 

var MyMenu: TMenuArray; 

procedure TMain.MyClickPopupMenu(Sender: TObject); 
begin 
    case TMenuItem(TMenuItem(Sender).Parent).Tag of 
     // do Something 
    end; 
end; 


procedure TMain.UpdateMenuReport; 
    procedure InitMyMenu(var AMenu: TMenuArray); 
    var i: Integer; 
    begin 
     if Length(AMenu)>0 then for i:= 0 to Length(AMenu)-1 do AMenu[i].Free; 
     SetLength(AMenu, 0); 
    end; 
var j, i: integer; 
begin 
    InitMyMenu(MyMenu); 
    Reports.Clear; 
    if DS.Active and (DS.RecordCount > 0) then 
    begin 
     SetLength(MyMenu, DS.RecordCount); 
     for i:= 0 to DS.RecordCount-1 do 
     begin 
      MyMenu[i] := TMenuItem.Create(Self); 
      MyMenu[i].Name := 'Reports_'+ IntToStr(i); 
      MyMenu[i].Caption := DS.FieldByname('NOM_REPORT').AsString; 
      MyMenu[i].Tag := DS.FieldByname('ID').AsInteger; 
      MyMenu[i].OnClick := MyClickPopupMenu; 
     end; 
    end; 
end; 

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

  • Нет связанных вопросов^_^