Recent

Author Topic: Mediators and Indexed Properties  (Read 634 times)

Weitentaaal

  • Sr. Member
  • ****
  • Posts: 499
  • Weitental is a very beautiful garbage depot.
Mediators and Indexed Properties
« on: November 30, 2023, 03:28:23 pm »
Is it Possible to tell a Mediator how to acces certain fields ?:

for  Example a Record as Property:

Code: Pascal  [Select][+][-]
  1.  
  2. TStages= record
  3.    stage1: double;
  4.    stage2: double;
  5.    stage3: double;
  6. end;
  7.  
  8. TSubject = class(TObservedHook)
  9. private
  10.    fStages: TMember;
  11. public
  12.    property Stage[index: integer] read GetStage write SetStage ;
  13. end;
  14.  

how would i do a Binding between GUI TEdit Fields ?
( stage1 <-> Edit1 | stage2 <-> Edit2 | stage3 <-> Edit4)

Checked TypInfo Unit and was searching for a Solution but could not really find anything that helps me. I pretty sure i'm overcomplicating it but how do i handle records in a Pattern like this ?
Lazarus: 2.0.12 x86_64-win64-win32/win64
Compiler Version: 3.2.2

sfeinst

  • Full Member
  • ***
  • Posts: 230
Re: Mediators and Indexed Properties
« Reply #1 on: November 30, 2023, 08:14:11 pm »
Since Mediator is an object you have to build, you can tell it to do whatever you want.  Depending on what you are really trying to acomplish, there are most likely multiple ways to do it.  But I would start with a few questions:
Is TSubject your Mediator or the Data Model?
Why are you using a record?  Do you have to?  Because I would lean towards either an array of double or a list of double pointers or possibly even a class?
In your TSubject, I assume TMember is a typo and should be TStages, or are you trying to do something else?

As for binding, that is all up to how you build your mediator.  You will want to look into OnEditingDone event for TEdits as that is your easiest way to to be notified when data changes in the edit (there are other events, but I like TEditingDone).

Your mediator would then tie a specific edit to a data location (could be some if tests, could be an index to an array, could be a pointer to a double, could be a map object, could be an array of record with edit and pointer as 2 values of the record).  OnEditingDone would either call the mediator diretly or you would have a list of listeners that the OnEditingEvent would call.  When you change a stage value, the mediator would need to know what is changing it so it doesn't get into a circular updating cycle with the updater getting called by the mediator (though I do not think OnEditingDone will cause this but you might update the edit an extra time which is avoidable).

Weitentaaal

  • Sr. Member
  • ****
  • Posts: 499
  • Weitental is a very beautiful garbage depot.
Re: Mediators and Indexed Properties
« Reply #2 on: December 01, 2023, 07:57:22 am »
Since Mediator is an object you have to build, you can tell it to do whatever you want.  Depending on what you are really trying to acomplish, there are most likely multiple ways to do it.  But I would start with a few questions:
Is TSubject your Mediator or the Data Model?
Why are you using a record?  Do you have to?  Because I would lean towards either an array of double or a list of double pointers or possibly even a class?
In your TSubject, I assume TMember is a typo and should be TStages, or are you trying to do something else?

As for binding, that is all up to how you build your mediator.  You will want to look into OnEditingDone event for TEdits as that is your easiest way to to be notified when data changes in the edit (there are other events, but I like TEditingDone).

Your mediator would then tie a specific edit to a data location (could be some if tests, could be an index to an array, could be a pointer to a double, could be a map object, could be an array of record with edit and pointer as 2 values of the record).  OnEditingDone would either call the mediator diretly or you would have a list of listeners that the OnEditingEvent would call.  When you change a stage value, the mediator would need to know what is changing it so it doesn't get into a circular updating cycle with the updater getting called by the mediator (though I do not think OnEditingDone will cause this but you might update the edit an extra time which is avoidable).

Yes the Subject would be the Data Model.
a record was the best option in my opinion so i went with it.
i do use OnEditingDone.
this line:    "fStages: TMember;" should be    "fStages: TStages;" (wanted to create a simple example to show you my problem).
The question i have: can i (and if so how?) bind a Mediator to a certain index of an indexed property. You did say "could be an index to an array", how do i tell the mediator to  use for Example the "Stage[0]" field for Edit1 and "Stage[1]" field for Edit2 and so on. Is this possible or would it make sense to completly change the type to an array, List etc.

i did always use "SetPropValue" methods from TypeInfo which worked on every simple Type for me. But now i tried to bind the Mediator to a certain field of a Value and failed.
Lazarus: 2.0.12 x86_64-win64-win32/win64
Compiler Version: 3.2.2

Zvoni

  • Hero Member
  • *****
  • Posts: 2237
Re: Mediators and Indexed Properties
« Reply #3 on: December 01, 2023, 10:37:35 am »
Agree with sfeinst: Would go with an array instead of a record.

If i have to "synchronize" GUI-Elements to some Data, i use an array of those Elements
Aircode
Code: Pascal  [Select][+][-]
  1. Uses SysUtils;
  2. Type
  3.    TSubject = Class(....)
  4. //Your definitions here
  5.    Protected
  6.       Function GetStage(AIndex:Integer):String;
  7.    Public
  8.       Constructor Create(AOwner:TObject);
  9.    End;
  10.  
  11.  
  12. Var
  13.  //DON'T START WITH "ARRAY START AT 0"
  14.    Stages:Array[1..3] Of Double;
  15.    ArrEdits:Array[1..3] Of TEdit;
  16.  
  17. Function TSubject.GetStage(AIndex:Integer):String;
  18. Begin
  19.    ArrEdits[AIndex].Text:=Stages[AIndex].ToString;
  20. End;
  21.  
  22. Constructor TSubject.Create(AOwner);
  23. Begin
  24.    Inherited Create(AOwner);
  25.    ArrEdits[1]:=TEdit1;
  26.    ArrEdits[2]:=TEdit2;
  27.    ArrEdits[3]:=TEdit3;
  28. //Anything else you want to do here
  29. End;
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

 

TinyPortal © 2005-2018