Avatar billede hrc Mester
24. oktober 2006 - 11:54 Der er 2 kommentarer og
1 løsning

TActionManager: Tilføjelse af TActions runtime

Jeg forsøger at tilføje TActions til min TActionManager og det driller. Er der en der kan fortælle hvad jeg gør forkert?

var
  Action : TAction;
  i : TAttributeTypes;
  TypeSet : TAttributeFilterSet;
  ClientItem : TActionClientItem;
begin
  fAttributList := TAttributList.Create;
  fAttributList.Filter := TAttributFilter.Create([]);
  TypeSet := TAttributFilter(fAttributList).TypeSet;

  ClientItem := amMenu.AddSeparator(amMenu.FindItemByAction(aUpdate));

  // Fyld data ind i menu - gennemløb typerne
  for i := succ(atUnknown) to high(TAttributeTypes) do
  begin
    Action := TAction.Create(self);
    Action.AutoCheck := true;
    Action.GroupIndex := 31;
    Action.Tag := integer(i);
    Action.Category := aUpdate.Category;
    Action.Caption := AttributeTypesText[i];
    Action.OnExecute := AttributeFilter;

    ClientItem := amMenu.AddAction(Action,ClientItem);

    include(TypeSet,i);
  end;
  TAttributFilter(fAttributList.Filter).TypeSet := TypeSet;

I min TActionMainMenuBar vises de oprettede actions fint under separatoren og aUpdate-action, men når jeg klikker på den får jeg en AV idet der foretages opslag i en TCustomActionList.GetAction der er nil.

Når jeg kigger i CostumizeDlg-dialogen så indeholder menu-kategorien ikke de manuelt oprettet actions. På en eller anden måde skal mine actions ind i samme actionlist som bl.a. aUpdate ligger i. Hvordan? Troede egentligt AddAction gjorde det for mig.

TAction.Create kaldes self som ejer, da det er samme som de design-time oprettede. Har prøvet med nil og amMenu.
Avatar billede hrc Mester
24. oktober 2006 - 13:03 #1
Nå jeg fik løst den selv. Kom forbi noget dokumentation jeg endnu ikke havde læst (den er altså blevet dårligere i D2006 i forhold til den gamle VCL-hjælp).

Det eneste jeg manglede var:

    Action := TAction.Create(self);
    Action.ActionList := amMenu; // << Denne linie løste det probelem.
    Action.AutoCheck := true;
    Action.GroupIndex := 31;
    Action.Tag := integer(i);
    Action.Category := aUpdate.Category;
    Action.Caption := AttributeTypesText[i];
    Action.OnExecute := AttributeFilter;

    ClientItem := amMenu.AddAction(Action,ClientItem);

    include(TypeSet,i);
Avatar billede hrc Mester
30. oktober 2006 - 09:46 #2
Nå der var nu mere i det end som så. Jeg har et TActionMainMenuBar hvori ovennævnte løsning fungerede fint. Problemet opstod da jeg ville lave en TActionToolBar og smække ikonerne på der.

Hvad jeg havde overset var, at en TActionClientItem er et plads-objekt der kan associeres med en TAction. Hvis jeg har en TActionClientItem i en TActionMainMenuBar og vil have tilsvarende knap i en TActionToolBar så skal jeg oprette en ny TActionClientItem for TActionToolBar'eren og tilknytte min TAction til den.

Problemet er bare, at bruger jeg TActionMainMenuBar til at oprette en TActionClientItem så er den tilknyttet TActionMainMenuBar. Hvis jeg prøver at ændre dette (da objektet har en TActionBar property), så får jeg en exception.

Da jeg endnu ikke har løst hvordan man opretter en ClientItem i en tom TActionToolBar, blev min løsning at trække et par actions over på bar'en. Når programmet kører kan jeg nu søge efter ClientItems i både TActionMainMenuBar og i TActionToolBar'en - og så kan jeg koble min TActions på det ene og det andet sted.

Koden - forbedringer er meget velkomne - er her:

var
  Action : TAction;
  i : TAttributTypes;
  ClientItem1 : TActionClientItem;
  ClientItem2 : TActionClientItem;
begin
  ClientItem1 := amMenu.FindItemByCaption('&Vis'); // Action manager assigns to menu
  ClientItem1.Items.Add.Caption := '-'; // make it a separator

  // Cannot figure out how to create a clientitem and assign it to an empty ActionToolBar.
  ClientItem2 := atbVis.FindLastVisibleItem; // Must have a visible one to function!
  ClientItem2.ParentItem.Items.Add.Caption := '-'; // Yet another separator

  // Add to TActionMainMenuBar
  for i := low(TAttributTypes) to high(TAttributTypes) do
    if not (i in [atUnknown]) then
    begin
      Action := TAction.Create(self); // Let the form do the houskeeping
      Action.AutoCheck := true;
      Action.ActionList := amMenu;
      Action.GroupIndex := 0;
      Action.Tag := integer(i);
      Action.Category := aUpdate.Category;
      Action.Caption := AttributTypesText[i];
      Action.Checked := true;
      Action.OnExecute := AttributeFilter;

      ClientItem1.Items.Add.Action := Action;

      // We need the parent item here...
      ClientItem2.ParentItem.Items.Add.Action := Action;
    end;

I det store hele så er det en komponentserie der er mig noget kryptisk at bruge ligeså snart man vil andet end at trække actions over på en menu.
Avatar billede hrc Mester
30. oktober 2006 - 10:58 #3
Nå ja, hvis ellers det har nogens interesse:

  ClientItem1 := amMenu.FindItemByCaption('&Vis'); // Find menu entry point for Vis
  ClientItem1.Items.Add.Caption := '-';

  // There's a thing called Type Casting...
  ClientItem2 := TActionClientItem(atbFilter.ActionClient);

  for i in (fKontaktList.Filter as TKontaktFilter).TypeSet do
  begin
    Action := TAction.Create(self);
    ...

    ClientItem1.Items.Add.Action := Action;
    ClientItem2.Items.Add.Action := Action;
  end;

Det virker tilsyneladende bedre og bedre. Havde dog et problem med at få punkterne under "&Vis" vist. Jeg skulle åbenbart rydde lidt op i DFM-filen via "Vis som tekst" (det der tidligere havde genvejen <Alt-f12> når man stod på en form (<Alt-f12> virker dog når man skal tilbage til formen igen)).

Selvom jeg havde fjernet menupunkterne så huskede TActionManageren kun alt for godt - og den eneste måde at fjerne tidligere tildelinger var at slette dem.

    ActionBars = <
      item
        Items = <
          item
            Items = <
              item
                Action = aNew
                Caption = '&Ny'
                ShortCut = 114
              end
              item
                Action = aEdit
                Caption = '&Ret'
                ShortCut = 113
              end>
            Caption = '&Kontakt'
          end
          item
            Items = <
              item
                Action = aUpdate
                Caption = '&Opdat'#233'r'
                ShortCut = 116
              end
              item
                Action = aVis
              end>
            Caption = '&Vis'
          end>
        ActionBar = ammbMenu
      end

      // Her lå der noget gammelt skrammel vedr atbFilter.

      item
        ActionBar = atbFilter
      end>
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester