Page 1 of 2 1 2 LastLast
Results 1 to 15 of 16

Thread: Sender achterhalen van een Grid bij gebruik van een Action.

  1. #1

    Sender achterhalen van een Grid bij gebruik van een Action.

    Hallo,

    Ik heb een Grid met hieraan gekoppeld een PopUpMenu. Aan elk MenuItem van het popupmenu is een Action gekoppeld.
    Mbv een ActionExecute wordt een procedure aangeroepen die op zijn beurt een nieuw form instantieert. Deze procedure wordt door meerdere grids met gekoppeld popupmenu gebruikt waardoor ik de sender van het grid moet zien te achterhalen.
    In post #2 van deze thread is een oplossing gegeven waarbij een Button gebruik maakt van een action. Deze code geeft echter, bij gebruik van een popupmenu, de Name van de Actionlist terug.
    Hoe kun je deze code aanpassen om de sender van het grid te verkrijgen?
    Last edited by robbedoes; 14-Feb-10 at 01:30. Reason: link toegevoegd

  2. #2
    Wat bedoel je met 'de sender van het grid'? Een grid heeft toch geen sender?

    [edit]
    Om alvast een greep naar een oplossing te doen: Een popupmenu heeft een property PopupComponent. Deze property wijst naar het component dat verantwoordelijk is voor het tonen van het popupmenu. Let op, dat werkt dus alleen als je het grid het popupmenu laat tonen en niet als je dat zelf doet met Popupmenu.Popup. In dat laatste geval kun je wel zelf die property zetten, zodat je die in het OnClick event van een menuitem weer kunt uitlezen.
    1+1=b

  3. #3
    Ik heb nu dit
    delphi Code:
    1. procedure TForm2.Action_ToonGevevensExecute(Sender: TObject);
    2. var
    3.   PopupScreen: TForm5;
    4. begin
    5.   If (Sender Is TBasicAction) And
    6.       (TBasicAction(Sender).ActionComponent Is TComponent) Then
    7.   begin
    8.     PopupScreen := TForm5.Create(application);
    9.     try
    10.       PopupScreen.GridName := TAdvStringGrid(Sender);
    11.       PopupScreen.CellPosition := TAdvStringGrid(Sender).SelectedCell[0];
    12.       PopupScreen.ShowModal;
    13.     finally
    14.       PopupScreen.Free;
    15.     end;
    16.   end;
    17. end;
    Ik krijg de Action event name als sender met deze code.

  4. #4
    DeX 3 Delphi := The ease of VB with the power of C; Zoekt en gij zult vinden

  5. #5
    @ Henkie,

    Heb je link bekeken en heb het nu zo opgelost.
    delphi Code:
    1. procedure TForm2.Action_ToonGevevensExecute(Sender: TObject);
    2. var
    3.   PopupScreen: TForm_PopUp;
    4. begin
    5.   If Assigned(ActiveControl) then
    6.     if (ActiveControl is TAdvStringGrid) then
    7.   begin
    8.     PopupScreen := TForm_PopUp.Create(application);
    9.     try
    10.       PopupScreen.GridName := TAdvStringGrid(ActiveControl);
    11.       PopupScreen.SelectedRowLine := TAdvStringGrid(ActiveControl).SelectedRow[0];
    12.       PopupScreen.ShowModal;
    13.     finally
    14.       PopupScreen.Free;
    15.     end;
    16.   end;
    17. end;
    Nog enkele vragen hierover.
    1) Is deze code correct geprogrammeerd?
    2) Begrijp ik het goed dat bij gebruik van ActiveControl, als het control precies na het aanroepen van de action_toongegevens de focus verliest, er een andere Sender wordt terug gegeven als waarvandaan de Action is getriggerd?

  6. #6
    2) Dat klopt
    1) Nee, zie 2.

    Wat mankeert er aan de oplossingen die in deze en in je eerdere thread zijn aangedragen?
    1+1=b

  7. #7
    Wat mankeert er aan de oplossingen die in deze en in je eerdere thread zijn aangedragen?
    De oplossing in mijn vorige thread geeft niet de naam van het component die de action vuurt maar van de action zelf.

    1) Nee, zie 2
    Vond ook al dat de code rammelde.
    Heb wat gestoeit met popupmenucomponent maar krijg geregeld een acces violation.

  8. #8
    Silly member NGLN's Avatar
    Join Date
    Aug 2004
    Location
    Werkendam
    Posts
    5,133
    Quote Originally Posted by robbedoes View Post
    1) Is deze code correct geprogrammeerd?
    Ja. Ik zou alleen de TForm_PopUp.GridName property in "Grid" veranderen. Het is immers geen String.
    2) Begrijp ik het goed dat bij gebruik van ActiveControl, als het control precies na het aanroepen van de action_toongegevens de focus verliest, er een andere Sender wordt terug gegeven als waarvandaan de Action is getriggerd?
    Dat zou betekenen dat die Action nogmaals wordt uitgevoerd. Waarom zou dat gebeuren? En zo dat het geval is, dan is dat toch gewoon weer een nieuwe situatie?

    Dus nee, de Sender is áltijd die ene Action (mits je die eventhandler niet handmatig aanroept, en die eventhandler niet aan meerdere Actions hebt toegewezen). En ja, ActiveControl verliest zijn waarde als hij zijn focus verliest. ActiveControl verwijst altijd naar het actieve control, da's de bedoeling. Maar ik begrijp niet welke relatie je tussen beide ziet.

    Je hoeft niet bang te zijn voor het verliezen van de focus van ActiveControl tijdens het uitvoeren van Action.OnExecute, tenzij je in die eventhandler zelf de focus op een ander control zet.

    Voor zover ik het begrijp heb je:
    - een Grid waaraan je een PopupMenu hebt gekoppeld,
    - een PopupMenu waarin MenuItems staan,
    - MenuItems waar je Actions aan hebt gekoppeld,
    - Actions die iets zouden moeten doen met het Grid waarvan het PopupMenu is geopend.

    Dan is in Action.OnExecute:
    - Sender de Action,
    - TAction(Sender).ActionComponent het MenuItem,
    - PopupMenu.PopupComponent het Grid,
    - ActiveControl het Grid.
    Maar de laatste twee stellingen kun je alleen vanuit gaan als die Action alléén aan een MenuItem op een PopupMenu is gekoppeld, én als dat PopupMenu alléén maar aan Grids is gekoppeld.

    Die aanname is in jouw geval waarschijnlijk wel juist, maar het is sowieso verstandig om te checken of ActiveControl überhaupt is toegewezen, en zo ja of hij dan een Grid is, zoals je al doet. Je kan de Action immers ook aan een Button koppelen, en dan is ActiveControl die Button. En je kunt ook het MenuItem van een MainMenu activeren, dan kun je niet van PopupMenu.PopupComponent uitgaan.

    Als in jouw code ActiveControl niet is toegewezen, dan weet je ook niet van welk Grid je de gegevens wilt hebben, dus doet de code niets. Prima.
    Idem in het geval dat ActiveControl wél is toegewezen, maar het niet een Grid is.

    ActiveControl biedt wel degelijk het antwoord op jouw vraag, en je code lijkt prima! Werkt die niet?
    Last edited by NGLN; 14-Feb-10 at 20:58.
    (Sender as TNLDUser).Signature := 'Groeten van Albert';

  9. #9
    ActiveControl biedt wel degelijk het antwoord op jouw vraag, en je code lijkt prima! Werkt die niet?
    Jawel, hij werkt perfect. was wat huiverig met de activecontrol en het verliezen van de focus. Volgens mij was dit ook GolezTrol zijn gedachten.

    Dat zou betekenen dat die Action nogmaals wordt uitgevoerd. Waarom zou dat gebeuren? En zo dat het geval is, dan is dat toch gewoon weer een nieuwe situatie?
    Inderdaad, zoals jij het stelt heb ik het nog niet bekeken. Als de action eenmaal gestart is dan maakt het niet meer uit of de focus van, in dit geval, de grid afgaat. De action wordt toch eerst uitgevoerd.
    Zucht... weer 1 1/2 uur aan het puzzelen geweest met popupcomponent. Maar goed weer wat geleerd.

    Bedankt.

  10. #10
    Ik zie nu dat je, in de tijd dat ik de voorgaande post aan het schrijven was, je post wat hebt aangepast.

    Je hoeft niet bang te zijn voor het verliezen van de focus van ActiveControl tijdens het uitvoeren van Action.OnExecute, tenzij je in die eventhandler zelf de focus op een ander control zet.
    Dat was inderdaad mijn gedachte gang. Vond mijn code niet helemaal waterdicht. In theorie kan het fout gaan als het component de focus verliest.

  11. #11
    In de praktijk zal het inderdaad wel meevallen. Het is inderdaad afhankelijk van de code die je in de action gebruikt. Die code hoeft niet perse het active control aan te passen. Ook wanneer er bijvoorbeeld Application.ProcessMessages in staat, loop je daarmee het risico dat activecontrol aangepast wordt. Dat kan dan zijn door interne code (bijvoorbeeld een timer die op dat moment verwerkt wordt), door user-interactie (twee toetsaanslagen snel na elkaar), of door invloed van buitenaf (een andere applictie die messages stuurt).

    De kans is niet groot, en zelfs een stuk kleiner dan ik net in een opwelling dacht, maar het geheel voelt gewoon als breekbare code.

    Maar ik snap sowieso niet waarom je vanuit een action moet weten van welk control die afkomstig is. Het doel van een action is juist dat je je acties kunt centraliseren en loskoppelen van die controls.
    Maar dat alles is maar gezever in de ruimte. Ik begrijp dat je code werkt, en dat NGLN 'm veilig genoeg vindt, dus wie ben ik om 'm af te keuren.
    1+1=b

  12. #12
    Silly member NGLN's Avatar
    Join Date
    Aug 2004
    Location
    Werkendam
    Posts
    5,133
    Hmm, in dat licht is het wellicht beter om de code als volgt te wijzigen:
    Delphi Code:
    1. procedure TForm2.Action_ToonGegevensExecute(Sender: TObject);
    2. var
    3.   Control: TControl;
    4.   PopupScreen: TForm_PopUp;
    5. begin
    6.   Control := ActiveControl;
    7.   If Assigned(Control) and (Control is TAdvStringGrid) then
    8.   begin
    9.     PopupScreen := TForm_PopUp.Create(Application);
    10.     try
    11.       PopupScreen.Grid := TAdvStringGrid(Control);
    12.       PopupScreen.SelectedRowLine := TAdvStringGrid(Control).SelectedRow[0];
    13.       PopupScreen.ShowModal;
    14.     finally
    15.       PopupScreen.Free;
    16.     end;
    17.   end;
    18. end;
    Nu mag ActiveControl zoveel wijzigen als dat ie wil...
    (Sender as TNLDUser).Signature := 'Groeten van Albert';

  13. #13
    @ NGLN,
    Mooie oplossing. Ga het meteen toepassen.
    Bedankt.
    Maar ik snap sowieso niet waarom je vanuit een action moet weten van welk control die afkomstig is.
    Ik heb meerdere grids in mijn applicatie. Na een rechtsklik op een rij in een willekeurige grid verschijnt er een popupmenu,waarna na selecteren van een item, een action wordt gestart die een soort van popupform instantieert wat getoont wordt met ShowModal. Op dit PopUpForm staat een richedit die gevuld wordt door gegevens die in de geselecteerde rij van het willekeurige grid staan. Vandaar dat ik moet weten welk grid de action gestart heeft. Als je een mooiere oplossing hebt hoor ik het graag.
    Last edited by robbedoes; 14-Feb-10 at 22:58. Reason: onduidelijkheid mbt popupmenu

  14. #14
    Volgens mij kom ik er gewoon met
    Code:
     (((Sender as TAction).ActionComponent as TMenuItem).GetParentMenu as TPopupMenu).PopupComponent
    Uitgeschreven in een functie wordt dat:
    Code:
    function GetPopupMenuActionTriggerComponent(Action: TAction): TComponent;
    var
      ActionComponent : TComponent;
      ParentMenu      : TMenu;
    begin
      // Vraag het component dat de action triggerde. Dat is het menuitem. 
      ActionComponent := Action.ActionComponent;
      // Zoek het parent menu van het menuitem. Dat is het popupmenu
      ParentMenu := (ActionComponent as TMenuItem).GetParentMenu;
      // Vraag het popupcomponent van het popupmenu. Dat is het 
      //component dat verantwoordelijk was voor het tonen van het popupmenu
      Result := (ParentMenu as TPopupMenu).PopupComponent;
    end;
    In een testje heb ik een memo, daaraan gekoppeld een popupmenu, met een item er in. Aan het item hangt een action en die action heeft een OnExecute met de volgende regel code:
    Code:
    // Sender van het event is de action
    ShowMessage(GetPopupMenuActionTriggerComponent(Sender as TAction).Name);
    Het resultaat na het klikken op het popupmenuitem is een melding met de tekst 'Memo1'.

    Zou runtime ook moeten lukken.

    [edit]
    Weer niet goed gelezen. 'Soort popupform' is vast geen popupmenu.

    Nou ja. Deze code heeft als nadeel dat het alleen werkt via dat popupmenu. Het werkt niet als je de action start via een shortcut ofzo.

    Het voordeel is wel dat popupmenu.PopupComponent altijd het grid blijft dat het menu heeft geopend. Als dus ActiveControl zou wijzigen terwijl het menu open staat, dan heeft dat geen invloed op deze code.
    Last edited by GolezTrol; 14-Feb-10 at 22:41.
    1+1=b

  15. #15
    Weer niet goed gelezen.
    Nou, je hebt het wel goed gelezen. Was niet duidelijk in mijn post. Heb het even aangepast.

    Ook weer een hele mooie oplossing. Dit verklaart waarom jij al meer dan 11000 posts hebt en ik een schamele 300.

    Ga het een en ander eens toepassen.

    Bedankt.

Page 1 of 2 1 2 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •