Autor Téma: Trieda, ktorá vráti rôzne typy komponentov  (Přečteno 778 krát)

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5615
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Trieda, ktorá vráti rôzne typy komponentov
« kdy: 23-01-2021, 10:26:55 »

Pokúšam sa vytvoriť triedu, ktorá mi vráti rôzne typy komponentov. Konkrétne sa jedná o TMS TDBxxSource pre TDBPlanner. Všetky sú potomkami TDBItems.
Použitie napríklad v SpinEdit, ktorý by obslúžil všetky TDBxxSource. Pre každý TDBxxSource existuje samostatný SpinEdit. Chcem mať pre ne len jedinú udalosť OnClick.
Trieda musí vrátiť, podľa indexu, konktrétny TDBxxSource. Nie TDBItems, lebo to by som musel pretypovať v OnClick. To je nezmysel. Trieda by stratila zmysel.
Príklad použitia
Kód: Delphi [Vybrat]
  1. procedure TfrmPlannerRole.advsedDayScaleChange(Sender: TObject);
  2. var
  3.   SpinEdit: TAdvSpinEdit;
  4. begin
  5.   SpinEdit := TAdvSpinEdit(Sender);
  6.   MyClass.DBSource(5).MyComponent := SpinEdit.Value;
  7. end;
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5615
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5615
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Trieda, ktorá vráti rôzne typy komponentov
« Odpověď #2 kdy: 23-01-2021, 13:59:44 »
Na vyjasnenie dávam príklady o čo mi ide
Kód: Delphi [Vybrat]
  1. procedure TfrmPlannerRole.advsedDayScaleChange(Sender: TObject);
  2. var
  3.   SpinEdit: TAdvSpinEdit;
  4. begin
  5.   SpinEdit := TAdvSpinEdit(Sender);
  6.   MyClass.DBSource(5).Top := SpinEdit.Value;  //  TPanel
  7. end;
  8.  
  9.  
  10. procedure TfrmPlannerRole.advsedDayScaleChange(Sender: TObject);
  11. var
  12.   SpinEdit: TAdvSpinEdit;
  13. begin
  14.   SpinEdit := TAdvSpinEdit(Sender);
  15.   MyClass.DBSource(3).Value := SpinEdit.Value;  //  TSpinEdit
  16. end;
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5615
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Trieda, ktorá vráti rôzne typy komponentov
« Odpověď #3 kdy: 23-01-2021, 18:00:44 »
Zobrali mi všetku nádej :'(  Nedá sa to.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pepak

  • Padawan
  • ******
  • Příspěvků: 1539
  • Karma: 37
    • Pepak.net
Re:Trieda, ktorá vráti rôzne typy komponentov
« Odpověď #4 kdy: 23-01-2021, 18:56:13 »
Ono se to možná dá, ale musel bys vysvětlit, co vlastně chceš. Já jsem to třeba nepochopil ani z tvých doplněných příkladů "na vyjasnění".

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5615
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Trieda, ktorá vráti rôzne typy komponentov
« Odpověď #5 kdy: 23-01-2021, 19:08:45 »
Nie si sám ;)
MyClass - trieda, ktorú chcem vytvoriť
DBSource(Idx: Integer) - metóda, ktorá na základe Idx vráti napr. TPanel, TSpinEdit atď.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3119
  • Karma: 136
    • Verze Delphi: D2007, XE3, DX10
Re:Trieda, ktorá vráti rôzne typy komponentov
« Odpověď #6 kdy: 23-01-2021, 19:38:53 »
Ono se to možná dá, ale musel bys vysvětlit, co vlastně chceš. Já jsem to třeba nepochopil ani z tvých doplněných příkladů "na vyjasnění".
Podle vseho chce nejaky helper, ktery pripomina factory na objekty, ovsem nechce, aby to vracelo jejich spolecneho predka, protoze by to musel stejne pretypovavat a AFAIK to jazyce se silnou typovou kontrolou nejde a  funkci nelze pretizit podle typu vracene hodnoty. Mozna, kdyby misto indexu pouzil unikatni typ, tak by se dala napsat sada pretizenych funkci. Ale v kazdem pripade je to divny pozadavek.

Offline pepak

  • Padawan
  • ******
  • Příspěvků: 1539
  • Karma: 37
    • Pepak.net
Re:Trieda, ktorá vráti rôzne typy komponentov
« Odpověď #7 kdy: 23-01-2021, 19:47:19 »
Nie si sám ;)
MyClass - trieda, ktorú chcem vytvoriť
DBSource(Idx: Integer) - metóda, ktorá na základe Idx vráti napr. TPanel, TSpinEdit atď.
Jestli tohle považuješ za vysvětlení, tak teda potěš koště. Co kdybys zapomněl na to, že tu budeš popisovat nějaké neexistující metody, které v tvé hlavě problém vysvětlují, a místo toho napsal, co je tvůj cíl, kterého chceš dosáhnout?

Podle vseho chce nejaky helper, ktery pripomina factory na objekty, ovsem nechce, aby to vracelo jejich spolecneho predka, protoze by to musel stejne pretypovavat
No a to je právě to, co chci zjistit. Ano, tak jak píše kód, tak to tak skoro vypadá, ale kdyby se snížil k popisu toho, co vlastně chce udělat, tak by to třeba nepotřeboval. Jsem tak napůl přesvědčený, že ve skutečnosti jeho problém jde řešit, ale samozřejmě ne tak, že bude vracet "různé typy objektů podle indexu", ale třeba přes RTTI. Jenže to jenom hádám, protože jsem se doteď nedozvěděl, co chce řešit.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5615
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Trieda, ktorá vráti rôzne typy komponentov
« Odpověď #8 kdy: 23-01-2021, 19:57:17 »

Mám obsahovo opakujúce sa udalosti (pre viac prípadov), kde sa mení "dbmlmnsrMultiMonth". Ako je táto:
Kód: Delphi [Vybrat]
  1. procedure TfrmPlannerRole.advsedMonthIncrementMultiMonthChange(Sender: TObject);
  2. var
  3.   SpinEdit: TAdvSpinEdit;
  4. begin
  5.   SpinEdit := TAdvSpinEdit(Sender);
  6.   dbmlmnsrMultiMonth.MonthIncrement := SpinEdit.Value;
  7. end;
  8.  
Rád by som to nahradil jedinou udalosťou pre každý prípad.
Kód: Delphi [Vybrat]
  1. procedure TfrmPlannerRole.advsedMonthIncrementMultiMonthChange(Sender: TObject);
  2. var
  3.   SpinEdit: TAdvSpinEdit;
  4. begin
  5.   SpinEdit := TAdvSpinEdit(Sender);
  6.   MyClass.DBSource(5).MonthIncrement := SpinEdit.Value;   // Vráti dbmlmnsrMultiMonth a spol.
  7. end;
  8.  
Nie je to nič život ohrozujúce. Ušetrenie riadkov a sústredenie riešenia do jedinej udalosti.
.
Edit

Ten problém nejde riešiť pomocou polí či generík. Aspoň ja o tom neviem.
« Poslední změna: 23-01-2021, 20:01:37 od Stanislav Hruška »
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3119
  • Karma: 136
    • Verze Delphi: D2007, XE3, DX10
Re:Trieda, ktorá vráti rôzne typy komponentov
« Odpověď #9 kdy: 23-01-2021, 19:59:31 »
Jenže to jenom hádám, protože jsem se doteď nedozvěděl, co chce řešit.
To nejsi sam, ja to taky jen odhaduju, protoze jestli ten popis je o nicem, tak ty priklady tuplem

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5615
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Trieda, ktorá vráti rôzne typy komponentov
« Odpověď #10 kdy: 23-01-2021, 20:29:15 »
Neviem čo je na tom nejasné. Mám niekoľko udalostí, ktoré sú obsahovo rovnaké. Len tam zakaždým použijem iný komponent. V uvedenom príklade mám dbmlmnsrMultiMonth.
A ja túto udalosť chcem použiť pre ďalšie komponenty čo robia to isté. Len s iným dbxxx.
.
Takže teraz mám 10 x SpineditxxxChange. A ja chcem jedinú udalosť SpineditxxxChange! Zakaždým tam potrebujem dostať ten správny dbxxx komponent.
Ja to už ináč vysvetliť neviem.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3119
  • Karma: 136
    • Verze Delphi: D2007, XE3, DX10
Re:Trieda, ktorá vráti rôzne typy komponentov
« Odpověď #11 kdy: 23-01-2021, 20:46:16 »
  MyClass.DBSource(5).MonthIncrement := SpinEdit.Value;   // Vráti dbmlmnsrMultiMonth a spol.
A kdyz ma byt ten handler jeden a spolecny pro nekolik spineditu, tak jak v nem muzes  mit natvrdo zapsan index (5)?
#
Jaky je vztah mezi Sender (spinEdit) a tim menicim se dbmlmnsrMultiMonth. Maji treba spolecneho parenta (panel), ktery je unikatni pro kazde dvojice spinedit+dbmlmnsrMultiMonth?

Offline pepak

  • Padawan
  • ******
  • Příspěvků: 1539
  • Karma: 37
    • Pepak.net
Re:Trieda, ktorá vráti rôzne typy komponentov
« Odpověď #12 kdy: 23-01-2021, 20:53:18 »
Nejde o to, že to máš vysvětlit jinak. Jde o to, že to máš vysvětlit nějak. Teď jsi konečně dal nějaké vysvětlení, sice napůl nesrozumitelné, ale nějaké. Předtím jsi dával ukázky kódu, který nefunguje, a snažil ses nám vnutit, že z toho je přece zřejmé, co chceš. Teď už mám aspoň nějakou představu. Sice mizernou, protože to tvoje vysvětlení je ze tří čtvrtin v tvé hlavě a jen ze čtvrtiny tady na fóru, ale aspoň nějakou. Takže bych řekl, že ve skutečnosti vůbec nechceš nic z toho, co jsi psal dosud, ale něco jako:

Kód: Delphi [Vybrat]
  1. type
  2.   TMujForm = class(TForm)
  3.   ...
  4.   private
  5.     SeznamDbxxxKomponent: array of TDbxxxKomponenta;
  6.       // Nebo TDirectory, TObjectList atd.
  7.   protected
  8.     procedure VsechnySpinEdityChange(Sender: TObject);
  9.   public
  10.     constructor Create(AOwner: TComponent); override;
  11.   end;
  12.  
  13. constructor TMujForm.Create(AOwner: TComponent);
  14. begin
  15.   inherited;
  16.   SetLength(SeznamDbxxxKomponent, 10);
  17.   SeznamDbxxxKomponent[0] := DbxxxKomponenta1;
  18.   SeznamDbxxxKomponent[1] := DbxxxKomponenta2;
  19.   // Slo by to i vice automaticky, ale opet - nevim, co presne chces a jake na to mas podminky
  20. end;
  21.  
  22. procedure TMujForm.VsechnySpinEdityChange(Sender: TObject);
  23. var
  24.   SpinEdit: TSpinEdit;
  25.   Index: integer;
  26. begin
  27.   if not (Sender is TSpinEdit) then
  28.     Exit;
  29.   SpinEdit := TSpinEdit(Sender);
  30.   Index := SpinEdit.Tag;
  31.     // Podle nejakeho kriteria prepocitat Sender na index do pole DbxxxKomponent
  32.   SeznamDbxxxKomponent[Index].MonthIncrement := SpinEdit.Value;
  33. end;
  34.  

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5615
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Trieda, ktorá vráti rôzne typy komponentov
« Odpověď #13 kdy: 23-01-2021, 21:01:49 »
To bol príklad a nad indexom som veľmi nepremýšľal. V skutočnosti tam bude CombBox.ItemIndex. Väzba je:
Items                           Komponent
Viac dní                        dbdysrMultiDay
Obdobie                       dbprsrPeriod
Obdobie poldeň            dbhldyprsrHalfDayPeriod
Mesiac                         dbmnsrMonth
Viac mesiacov              dbmlmnsrMultiMonth
Časová os                    dbtmlnsrTimeLine
Aktívne dni                  dbacdysrActiveDay
Obdobie akt. dni          dbacdyprsrActiveDayPeriod

a mám   TViews = (vwMultiDay, vwPeriod, vwHalfDayPeriod, vwMonth, vwMultiMonth, vwTimeLine, vwActiveDay, vwActiveDayPeriod);
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5615
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Trieda, ktorá vráti rôzne typy komponentov
« Odpověď #14 kdy: 23-01-2021, 21:09:55 »
Problém je v
Kód: Delphi [Vybrat]
  1. private
  2.     SeznamDbxxxKomponent: array of TDbxxxKomponenta;
  3.       // Nebo TDirectory, TObjectList atd.
TDbxxxKomponenta je vždy iný typ. Viď príspevok nižšie. To je celé jadro problému. Pochádzajú síce z TDBItems, ale to mi nijako nepomôže.
Preto to neviem vyriešiť. V mieste použitia by som to musel pretypovať a tým to je celé v háji.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.