🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.delphi
20 messages
20 total messages Started by ExM Thu, 05 Apr 2018 15:49
Nowy komponent - gdzie Parent?
#346536
Author: ExM
Date: Thu, 05 Apr 2018 15:49
23 lines
2161 bytes
W końcu życie mnie zmusiło do stworzenia własnego komponentu - listy rozwijanej TComboBox połączonego z TEdit
Nowy komponent tworzę na bazie TComboBox a w konstruktorze dynamicznie tworzę pole TEdit.

W apce mi to działa:

  edEdit := TEdit.Create(nil);
  edEdit.Parent := Self;
  edEdit.Left   := 10; 
  edEdit.Top    := 10; 
  edEdit.Width  := 100;
  edEdit.Height := 20; 

Ale w komponencie muszę wskazać jaki jest prawidłowy [Parent]
Kiedy podaje [Self] to jest ok - ale pole na nowy TEdit mam ograniczone do obszaru który zajmuje TComboBox 

Próbowałem podać:
  edEdit.Parent := Parent;

- bo wydawało mi się że zmienna Parent w konstruktorze jest de facto obiektu TComboBox - ale wtedy nic mi się nie pojawia 

Możecie podpowiedzieć - jak prawidłowo wskazać rodzica na którym chce położyć nowy TEdit tworzony w konstruktorze nowego komponentu?

Dzięki za pomoc!
Re: Nowy komponent - gdzie Parent?
#346537
Author: Adam Siwoń
Date: Thu, 05 Apr 2018 17:33
36 lines
2470 bytes
W dniu 2018-04-05 o 17:49, ExM pisze:
> W końcu życie mnie zmusiło do stworzenia własnego komponentu - listy rozwijanej TComboBox połączonego z TEdit
> Nowy komponent tworzę na bazie TComboBox a w konstruktorze dynamicznie tworzę pole TEdit.
> 
> W apce mi to działa:
> 
>    edEdit := TEdit.Create(nil);

Nie lepiej wywołać TEdit.Create(Self)? Edit zostanie zwolniony wraz z 
formą i nie będziesz musiał robić tego ręcznie.

>    edEdit.Parent := Self;
>    edEdit.Left   := 10;
>    edEdit.Top    := 10;
>    edEdit.Width  := 100;
>    edEdit.Height := 20;
> 
> Ale w komponencie muszę wskazać jaki jest prawidłowy [Parent]
> Kiedy podaje [Self] to jest ok - ale pole na nowy TEdit mam ograniczone do obszaru który zajmuje TComboBox
> 
> Próbowałem podać:
>    edEdit.Parent := Parent;
> 
> - bo wydawało mi się że zmienna Parent w konstruktorze jest de facto obiektu TComboBox - ale wtedy nic mi się nie pojawia
> 
> Możecie podpowiedzieć - jak prawidłowo wskazać rodzica na którym chce położyć nowy TEdit tworzony w konstruktorze nowego komponentu?

Ta druga próba jest poprawna tylko pewnie w konstruktorze ComboBoxa 
Parent nie jest jeszcze przypisany (ma wartość nil) i to samo ustawiasz 
dla edita. Spróbuj przeciążyć metodę SetParent ComboBoxa (jest 
wirtualna) i tam ustawiaj Parent dla edita jak już pojawi się wartość 
Parent w Comboboxie.

-- 
z pozdrowieniami
Adam Siwoń
Re: Nowy komponent - gdzie Parent?
#346538
Author: Roman Tyczka
Date: Thu, 05 Apr 2018 17:39
33 lines
2061 bytes
On Thu, 5 Apr 2018 08:49:42 -0700 (PDT), ExM wrote:

> W końcu życie mnie zmusiło do stworzenia własnego komponentu - listy rozwijanej TComboBox połączonego z TEdit

A do czego Ci potrzebny nowy komponent? Czego nie ma TComboBox?

> Nowy komponent tworzę na bazie TComboBox a w konstruktorze dynamicznie tworzę pole TEdit.
> 
> W apce mi to działa:
> 
>   edEdit := TEdit.Create(nil);
>   edEdit.Parent := Self;
>   edEdit.Left   := 10; 
>   edEdit.Top    := 10; 
>   edEdit.Width  := 100;
>   edEdit.Height := 20; 
> 
> Ale w komponencie muszę wskazać jaki jest prawidłowy [Parent]
> Kiedy podaje [Self] to jest ok - ale pole na nowy TEdit mam ograniczone do obszaru który zajmuje TComboBox 
> 
> Próbowałem podać:
>   edEdit.Parent := Parent;
> 
> - bo wydawało mi się że zmienna Parent w konstruktorze jest de facto obiektu TComboBox - ale wtedy nic mi się nie pojawia 
> 
> Możecie podpowiedzieć - jak prawidłowo wskazać rodzica na którym chce położyć nowy TEdit tworzony w konstruktorze nowego komponentu?

To raczej załatwia Owner, a nie Parent. Parent dotyczy miejsca
wyświetania/rysowania.

-- 
pozdrawiam
Roman Tyczka
Re: Nowy komponent - gdzie Parent?
#346540
Author: Marek
Date: Fri, 06 Apr 2018 06:12
12 lines
1418 bytes
W dniu 2018-04-05 o 17:49, ExM pisze:
> W końcu życie mnie zmusiło do stworzenia własnego komponentu - listy rozwijanej TComboBox połączonego z TEdit
> Nowy komponent tworzę na bazie TComboBox a w konstruktorze dynamicznie tworzę pole TEdit.
> (..)
> Możecie podpowiedzieć - jak prawidłowo wskazać rodzica na którym chce położyć nowy TEdit tworzony w konstruktorze nowego komponentu?

  Zbuduj komponent na bazie panelu i na nim połóż combo i edit-a, dla których panel będzie parent-em.


-- 
Pzdr.
Marek
Re: Nowy komponent - gdzie Parent?
#346539
Author: ExM
Date: Fri, 06 Apr 2018 12:23
9 lines
2025 bytes
W dniu czwartek, 5 kwietnia 2018 19:39:17 UTC+2 użytkownik Roman Tyczka napisał:
> On Thu, 5 Apr 2018 08:49:42 -0700 (PDT), ExM wrote:
> 
> > W końcu życie mnie zmusiło do stworzenia własnego komponentu - listy rozwijanej TComboBox połączonego z TEdit
> 
> A do czego Ci potrzebny nowy komponent? Czego nie ma TComboBox?
 
Generalnie chodzi o możliwość filtrowania na TComboBox który ma powiedzmy 200 elementów. W tym celu filtruję listę tak aby zawierała tylko elementy zawierające wprowadzone w TEdit tekst.
W przykładzie podałem uproszczoną wersję bo chodzi o TDBLookupComboBox - a właściwie jej zmodyfikowaną wersję posiadającą jeszcze inne funkcje.
Re: Nowy komponent - gdzie Parent?
#346541
Author: ExM
Date: Fri, 06 Apr 2018 12:31
15 lines
1977 bytes
Ok. część problemu rozwiązałem.

Teraz jeszcze mam problem z nadpisaniem (?) zdarzenia OnClick
- chciałbym aby przed/po wykonaniu przypiętej do nowego obiektu procedury w chwili zdarzenia OnClick wykonał się jeszcze fragment mojego kodu.

Jak to powinienem zrobić?
Z jednej strony jak mi się wydaje powinna być taka właściwość:
  published
    property OnClick : TNotifyEvent read FOnClick write FOnClick;

i do niej zmienna:
  private
    FOnClick  : TNotifyEvent;

Ale gdzie mam dodać kod który wykona się w chwili zdarzenia?
Re: Nowy komponent - gdzie Parent?
#346542
Author: Piotr S.
Date: Fri, 06 Apr 2018 13:43
22 lines
1679 bytes
W dniu 2018-04-06 o 14:31, ExM pisze:
> Ok. część problemu rozwiązałem.
> 
> Teraz jeszcze mam problem z nadpisaniem (?) zdarzenia OnClick
> - chciałbym aby przed/po wykonaniu przypiętej do nowego obiektu procedury w chwili zdarzenia OnClick wykonał się jeszcze fragment mojego kodu.
> 
> Jak to powinienem zrobić?
> Z jednej strony jak mi się wydaje powinna być taka właściwość:
>    published
>      property OnClick : TNotifyEvent read FOnClick write FOnClick;
> 
> i do niej zmienna:
>    private
>      FOnClick  : TNotifyEvent;
> 
> Ale gdzie mam dodać kod który wykona się w chwili zdarzenia?
> 

Musisz przeciążyć odpowiednią metodę Click

Pozdrawiam
P.S.
Re: Nowy komponent - gdzie Parent?
#346543
Author: ExM
Date: Fri, 06 Apr 2018 14:02
22 lines
2469 bytes
W dniu piątek, 6 kwietnia 2018 15:42:53 UTC+2 użytkownik Piotr S. napisał:
> > Jak to powinienem zrobić?
> > Z jednej strony jak mi się wydaje powinna być taka właściwość:
> >    published
> >      property OnClick : TNotifyEvent read FOnClick write FOnClick;
> > 
> > i do niej zmienna:
> >    private
> >      FOnClick  : TNotifyEvent;
> > 
> > Ale gdzie mam dodać kod który wykona się w chwili zdarzenia?
> > 
> 
> Musisz przeciążyć odpowiednią metodę Click


Tak się domyślam, tylko nie za bardzo jeszcze łapię jak to wygląda przy komponentach. Bo z jednej stronie jest:  property OnClick 
a z drugiej obsługa procedury OnClick? - razem nie mogą one występować...

Szukam przykładów, przeczytałem pare artykułów z 4programmers o budowie nowych komponentów ale nie mogę tam znaleźć analogii.

Może ktoś podesłać jakiś przykład komponentu który dziedziczy OnClick i równocześnie przeciąża jego obsługę?
Re: Nowy komponent - gdzie Parent?
#346544
Author: ExM
Date: Fri, 06 Apr 2018 14:04
1 lines
1737 bytes
Wystarczył by mi jakiś nowy TEdit który w OnClick wyczyści zawartość Text i następnie wykona oryginalną procedurę przypisaną do OnClick nowego komponentu.
Re: Nowy komponent - gdzie Parent?
#346545
Author: wloochacz
Date: Fri, 06 Apr 2018 15:10
21 lines
2193 bytes
W dniu 2018-04-06 o 16:04, ExM pisze:
> Wystarczył by mi jakiś nowy TEdit który w OnClick wyczyści zawartość Text i następnie wykona oryginalną procedurę przypisaną do OnClick nowego komponentu.

To otwórz IDE i poszukaj w kodzie co wywołuje zdarzenie OnClick.
Podpowiem Ci:
TComboBox -> TCustomComboBox -> TCustomCombo -> TCustomListControl -> 
TWinControl -> TControl

I na poziomie TControl masz chronioną metodę (protected) Click, a w niej 
komentarz:
   { Call OnClick if assigned and not equal to associated action's 
OnExecute.
     If associated action's OnExecute assigned then call it, otherwise, call
     OnClick. }

Co masz zrobić?
Przeciążyć metodę Click na poziomie własnego komponentu i dopisać co Ci 
potrzebne.

-- 
wloochacz
Re: Nowy komponent - gdzie Parent?
#346546
Author: ExM
Date: Fri, 06 Apr 2018 18:05
39 lines
2936 bytes
W dniu piątek, 6 kwietnia 2018 17:10:06 UTC+2 użytkownik wloochacz napisał:
> W dniu 2018-04-06 o 16:04, ExM pisze:
> > Wystarczył by mi jakiś nowy TEdit który w OnClick wyczyści zawartość Text i następnie wykona oryginalną procedurę przypisaną do OnClick nowego komponentu.
> 
> To otwórz IDE i poszukaj w kodzie co wywołuje zdarzenie OnClick.
> Podpowiem Ci:
> TComboBox -> TCustomComboBox -> TCustomCombo -> TCustomListControl -> 
> TWinControl -> TControl
> 
> I na poziomie TControl masz chronioną metodę (protected) Click, a w niej 
> komentarz:
>    { Call OnClick if assigned and not equal to associated action's 
> OnExecute.
>      If associated action's OnExecute assigned then call it, otherwise, call
>      OnClick. }
> 
> Co masz zrobić?
> Przeciążyć metodę Click na poziomie własnego komponentu i dopisać co Ci 
> potrzebne.
> 
> -- 
> wloochacz

Jeah!
Na to właśnie czekałem :) 
Nie wiedziałem że OnClick jest de facto procedurą Click i to tak głęboko dziedziczoną. 

Zrobiłem - działa :) Dzięki za podpowiedź!

Protected
  { Protected declarations }
  procedure Click; override;

procedure TMojTestowyKomponent.Click;
Begin
 inherited;
 Selft.Tag := 1; //czysto do testów 

end;
Re: Nowy komponent - gdzie Parent?
#346547
Author: zpksoft
Date: Sat, 07 Apr 2018 09:05
18 lines
2297 bytes
W dniu piątek, 6 kwietnia 2018 08:12:18 UTC+2 użytkownik Marek napisał:
> W dniu 2018-04-05 o 17:49, ExM pisze:
> > W końcu życie mnie zmusiło do stworzenia własnego komponentu - listy rozwijanej TComboBox połączonego z TEdit
> > Nowy komponent tworzę na bazie TComboBox a w konstruktorze dynamicznie tworzę pole TEdit.
> > (..)
> > Możecie podpowiedzieć - jak prawidłowo wskazać rodzica na którym chce położyć nowy TEdit tworzony w konstruktorze nowego komponentu?
> 
>   Zbuduj komponent na bazie panelu i na nim połóż combo i edit-a, dla których panel będzie parent-em.
> 
> 
> -- 
> Pzdr.
> Marek

Można prościej: ja bym zrezygnował z TEdit - zamiast tego utworzył bym stringlistę pamiętającą pełną listę a w combo w onchange zawężał bym listę do tej spełniającą warunek klucza. 
Po Esc można by listę przywrócić do pełnej.

Paweł
Re: Nowy komponent - gdzie Parent?
#346548
Author: ExM
Date: Sat, 07 Apr 2018 10:27
1 lines
1944 bytes
Tak by było prościej gdyby docelowo to był TComboBox, ale jak pisałem wcześniej taki podałem przykład dla uproszczenia opisu. Tak naprawdę to modyfikuje pewną odmianę TDbLookupComboBox którego zawartość modyfikuje poprzez metodę Filter := 'Name like %szukany%'; To mi z automatu załatwia filtrowanie i listę rozwijaną. TEdit był mi potrzebny aby można było wprowadzać szukaną wartość.
Re: Nowy komponent - gdzie Parent?
#346549
Author: J-23
Date: Sat, 07 Apr 2018 12:40
10 lines
1837 bytes
W dniu 07.04.2018 o 12:27, ExM pisze:
> Tak by było prościej gdyby docelowo to był TComboBox, ale jak pisałem wcześniej taki podałem przykład dla uproszczenia opisu. Tak naprawdę to modyfikuje pewną odmianę TDbLookupComboBox którego zawartość modyfikuje poprzez metodę Filter := 'Name like %szukany%'; To mi z automatu załatwia filtrowanie i listę rozwijaną. TEdit był mi potrzebny aby można było wprowadzać szukaną wartość.
> 
To skoro tak to czemu TEdit? a nie TDBEdit wtedy masz jeszcze prościej 
bo podpinasz tylko DataSource. Nie wiem jak masz realizowane pobieranie 
danych w tym komponencie ale kieruj się tym że komponent powinien być 
jak najbardziej uniwersalny.

Pozdrawiam
J-23
Re: Nowy komponent - gdzie Parent?
#346554
Author: zpksoft
Date: Sun, 08 Apr 2018 08:38
6 lines
2189 bytes
W dniu sobota, 7 kwietnia 2018 12:27:33 UTC+2 użytkownik ExM napisał:
> Tak by było prościej gdyby docelowo to był TComboBox, ale jak pisałem wcześniej taki podałem przykład dla uproszczenia opisu. Tak naprawdę to modyfikuje pewną odmianę TDbLookupComboBox którego zawartość modyfikuje poprzez metodę Filter := 'Name like %szukany%'; To mi z automatu załatwia filtrowanie i listę rozwijaną. TEdit był mi potrzebny aby można było wprowadzać szukaną wartość.

Mała uwaga: jeżeli to jest Firebird  to spróbuj zamiast like %szukany% użyć containing szukany. Będziesz miał szukanie bez względu na wielkość liter.

Paweł
Re: Nowy komponent - gdzie Parent?
#346555
Author: ExM
Date: Sun, 08 Apr 2018 19:41
7 lines
2005 bytes
W dniu niedziela, 8 kwietnia 2018 10:38:56 UTC+2 użytkownik zpksoft napisał:
> Mała uwaga: jeżeli to jest Firebird  to spróbuj zamiast like %szukany% użyć containing szukany. Będziesz miał szukanie bez względu na wielkość liter.
> 
> Paweł

Dzięki za info, ale akurat korzystam z SDAC do MSSQL a aby uzyskać ten efekt użyłem opcji:
 ListSource.DataSet.FilterOptions := [foCaseInsensitive];
Re: Nowy komponent - gdzie Parent?
#346550
Author: ExM
Date: Sun, 08 Apr 2018 19:46
45 lines
2937 bytes
W dniu sobota, 7 kwietnia 2018 14:41:05 UTC+2 użytkownik J-23 napisał:
> To skoro tak to czemu TEdit? a nie TDBEdit wtedy masz jeszcze prościej 
> bo podpinasz tylko DataSource. Nie wiem jak masz realizowane pobieranie 
> danych w tym komponencie ale kieruj się tym że komponent powinien być 
> jak najbardziej uniwersalny.
> 
> Pozdrawiam
> J-23

Tak się właśnie zastanawiam czy TDBEdit byłby lepszy...
Nie za bardzo znajduje pomysł do użycia

TEdit używam tylko do przekazania wprowadzonej wartości do ustawienia filtra. Podstawowe działanie oparłem na OnEditChange:
-------------------------------------------------------------

procedure TDBLookupListComboBox.OnEditChange(Sender: TObject);
Begin

 //Szukamy 
 if edEdit.Text <> '' then Begin

   ListSource.DataSet.Filtered := False;
   ListSource.DataSet.Filter   :=  ListField + ' Like ''%'+edEdit.Text+'%''';

   if Length(edEdit.Text) > 0 then Begin
     ListSource.DataSet.FilterOptions := [foCaseInsensitive];
     ListSource.DataSet.Filtered      := True;
     DropDown;
   end;

 end else Begin
   ListSource.DataSet.Filtered:=False;
   DropDown;
 end;

end;

Do tego dołączyłem jeszcze OnExit i działa piknie :) 
-------------------------------------------------------------

procedure TDBLookupListComboBox.OnEditExit(Sender: TObject);
Begin
 CloseUp(True);
 ListSource.DataSet.Filtered := False;
end;
Re: Nowy komponent - gdzie Parent?
#346551
Author: J-23
Date: Sun, 08 Apr 2018 22:18
44 lines
2489 bytes
W dniu 08.04.2018 o 21:46, ExM pisze:
> 
> Tak się właśnie zastanawiam czy TDBEdit byłby lepszy...
> Nie za bardzo znajduje pomysł do użycia
> 
> TEdit używam tylko do przekazania wprowadzonej wartości do ustawienia filtra. Podstawowe działanie oparłem na OnEditChange:
> -------------------------------------------------------------
> 
> procedure TDBLookupListComboBox.OnEditChange(Sender: TObject);
> Begin
> 
>   //Szukamy
>   if edEdit.Text <> '' then Begin
> 
>     ListSource.DataSet.Filtered := False;
>     ListSource.DataSet.Filter   :=  ListField + ' Like ''%'+edEdit.Text+'%''';
> 
>     if Length(edEdit.Text) > 0 then Begin
>       ListSource.DataSet.FilterOptions := [foCaseInsensitive];
>       ListSource.DataSet.Filtered      := True;
>       DropDown;
>     end;
> 
>   end else Begin
>     ListSource.DataSet.Filtered:=False;
>     DropDown;
>   end;
> 
> end;
> 
> Do tego dołączyłem jeszcze OnExit i działa piknie :)
> -------------------------------------------------------------
> 
> procedure TDBLookupListComboBox.OnEditExit(Sender: TObject);
> Begin
>   CloseUp(True);
>   ListSource.DataSet.Filtered := False;
> end;
> 

Skoro działa to ok :)

Pozdrawiam
J-23
Re: Nowy komponent - gdzie Parent?
#346552
Author: Krzysztof Szyszka
Date: Mon, 09 Apr 2018 18:29
43 lines
3628 bytes
> > To skoro tak to czemu TEdit? a nie TDBEdit wtedy masz jeszcze prościej
> > bo podpinasz tylko DataSource. Nie wiem jak masz realizowane pobieranie
> > danych w tym komponencie ale kieruj się tym że komponent powinien być
> > jak najbardziej uniwersalny.
> >
> > Pozdrawiam
> > J-23
>
> Tak się właśnie zastanawiam czy TDBEdit byłby lepszy...
> Nie za bardzo znajduje pomysł do użycia

Bo to nie jest najlepszy pomysł. TDBEdit zapisuje dane do pola tabeli, a Tobie to po co?
Ty potrzebujesz tylko okienko do wprowadzenia tekstu filtra. Wystarczy TEdit, albo TComboBox,
jeśli chciałbyś pamiętać wszystkie wpisywane wcześniej teksty i umożliwić wybieranie ich z listy.

> TEdit używam tylko do przekazania wprowadzonej wartości do ustawienia filtra. Podstawowe działanie
> oparłem na OnEditChange:

Jeśli chcesz z tego zrobić samodzielny komponent, to podziel temat na dwa zadania:

1. Definiujesz nowe property ListFilter, które przechowuje aktualną treść filtra dla ListSource.
Aktualną zawartość ListFilter ustawiasz w przeciążonej metodzie DropDown i usuwasz w metodzie
CloseUp, a nie trzymasz ustawionego filtra na ListSource, bo dla innych rekordów możesz mieć dane
spoza zakresu filtra i wtedy nie zobaczysz prawidłowej wartości danych w innych rekordach.

2. Do zmiany zawartości ListFilter potrzebujesz osobnej kontrolki edycyjnej np. TEdit, ale nie widzę
powodu, żeby ta kontrolka była widoczna cały czas na ekranie. Wystarczy pokazać ją użytkownikowi
np. po naciśnięciu F4 i ukryć po wprowadzeniu tekstu filtra i naciśnięciu Enter. Wprowadzony tekst
jedynie zmienia aktualny stan ListFilter. Taką kontrolkę możesz utworzyć dynamicznie wtedy,
gdy chcesz ją pokazać, najlepiej w tym samym miejscu, co główny komponent (ponad nim).

3. Jeśli jednak będziesz się upierał, żeby treść filtra była cały czas widoczna na ekranie, to 
musisz
utworzyć w konstruktorze TEdit, który będzie się przesuwał wraz z głównym komponentem.
Parenta dla TEdit najlepiej ustawić w metodzie SetParent głównego komponentu, ale będziesz
musiał pokryć jeszcze kilka innych metod, żeby to sensownie działało w trybie design-time.

-- 
pozdrowienia
Krzysztof Szyszka, X-Files Software
Developer of X-DBGrid Component
Embarcadero Technology Partner
http://www.x-files.pl/ 
Re: Nowy komponent - gdzie Parent?
#346553
Author: ExM
Date: Tue, 10 Apr 2018 10:40
20 lines
2499 bytes
W dniu poniedziałek, 9 kwietnia 2018 20:30:20 UTC+2 użytkownik Krzysztof Szyszka napisał:

> 3. Jeśli jednak będziesz się upierał, żeby treść filtra była cały czas widoczna na ekranie, to 
> musisz
> utworzyć w konstruktorze TEdit, który będzie się przesuwał wraz z głównym komponentem.
> Parenta dla TEdit najlepiej ustawić w metodzie SetParent głównego komponentu, ale będziesz
> musiał pokryć jeszcze kilka innych metod, żeby to sensownie działało w trybie design-time.
> 
> -- 
> pozdrowienia
> Krzysztof Szyszka, X-Files Software
> Developer of X-DBGrid Component
> Embarcadero Technology Partner
> http://www.x-files.pl/

Dzięki za pomocne uwagi.
Po zrealizowaniu tak to działa:
https://screenpresso.com/=T5EP

To bardzo upraszcza przeglądanie dużych list :)
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads