带有默认popupmenu项的delphi自定义组件

时间:2019-04-16 12:28:42

标签: delphi components popupmenu

我使用一个自定义的listview组件,我需要它具有一个popupmenu项“将数据复制到剪贴板”。如果没有分配的弹出窗口,则创建一个并添加菜单项;如果已经分配了菜单,则将该项目添加到当前弹出窗口。试图将代码放入构造函数中,但是后来我意识到,popupmenu仍未创建或未关联到我的列表视图。那么什么时候创建我的默认项目呢?

$colors : (
  'blue'  : #1a4b84,
  'green' : #d9534f,
  'orange': #c9302c
);

@each $color_name, $color in $colors {
  .tabs--boxs{
    .#{$color_name}-color-box{
      .box-title{
        &::after { border-bottom-color: $color }
      }
    }
  }
}

2 个答案:

答案 0 :(得分:1)

覆盖虚拟TControl.DoContextPopup()方法,例如:

type
  TMyListView = class(TListView)
  protected
    ...
    procedure DoContextPopup(MousePos: TPoint; var Handled: Boolean); override;
    ...
  end;

procedure TMyListView.DoContextPopup(MousePos: TPoint; var Handled: Boolean);
var
  LPopupMenu: TPopupMenu;
  LItem: TMenuItem;

  function IsSameEvent(const E1, E2: TNotifyEvent): Boolean;
  begin
    Result := (TMethod(E1).Code = TMethod(E2).Code) and
              (TMethod(E1).Data = TMethod(E2).Data);
  end;

begin
  inherited DoContextPopup(MousePos, Handled);
  if Handled then Exit;

  LPopupMenu := PopupMenu;
  if not Assigned(LPopupMenu) then
  begin
    LPopupMenu := TPopupMenu.Create(Self);
    PopupMenu := LPopupMenu;
  end;

  for I := 0 to LPopupMenu.Items.Count-1 do
  begin
    LItem := LPopupMenu.Items[I];
    if IsSameEvent(LItem.OnClick, PopupMenuItemClick) then
      Exit;
  end;

  LItem := TMenuItem.Create(Self);
  LItem.Caption := 'Copy data to clipboard';
  LItem.OnClick := PopupMenuItemClick;
  LPopupMenu.Items.Add(LItem);
end;

答案 1 :(得分:0)

可接受的答案确实可以完美地工作-除非您在菜单项中添加键盘快捷键。如果这样做,在以其他方式访问弹出菜单之前,这些将不起作用,因为将不会创建项目。 如果需要快捷方式,则最好将代码从DoContextPopup移到Loaded。最简单地

procedure Loaded; override;
...
procedure Loaded; 
var 
  MI: TMenuItem;
  ItemCovered: boolean;
  i: integer;
begin
  inherited;
  if not Assigned(PopupMenu) then 
    PopupMenu:=TPopupMenu.Create(self);
  ItemCovered:=false;
  for i := 0 to PopupMenu.Items.Count-1 do
    if IsSameEvent(PopupMenu.Items[I].OnClick, CopyDataToClipboardClick) then begin 
      ItemCovered:=true;
      break;
    end;
  if not ItemCovered then begin
    MI:=TMenuItem.Create(PopupMenu);
    MI.Caption:='Copy data to clipboard';
    MI.OnClick:=CopyDataToClipboardClick;
    MI.ShortCut:=ShortCut(Ord('C'),[ssShift,ssCtrl]);
    PopupMenu.Items.Add(MI);
  end;
end;

这不会检查运行时添加的弹出菜单,但在大多数情况下可能会更好。