![]() |
Änderungen in TList verfolgen
Moin, Moin.
Bin dabei eine neue Stringgrid-Komponente zu entwerfen. Die Daten werden nicht im Grid, sondern in einer TList vorgehalten. Dafür ist eine Interaktion zwischen der Liste und dem Grid notwendig: So muss z.B. das sortierte Grid erfahren, wenn Datensätze in TList aufgenommen oder gelöscht wurden. Zuerst war mein Ansatz, die Methoden Add, Extract und Delete in einer Ableitung von TList zu überschreiben und darin meine Benachrichtigung an das Grid einzufügen. Geht aber nicht: "Statische Methoden können nicht überschrieben werden". Hm, dann bin ich in CLASSES über eine "leere" Prozedur von TList gestolpert, die in der Hilfe nicht erwähnt wird: TList.Notify() - damit geht es auch, sehr schön :-D
Delphi-Quellcode:
Nun gibt es aber doch noch ein kleines Problem: Das Grid arbeitet mit zwei Listen. Eine enthält alle Datensätze, die zweite Liste nur die gefilterten Datensätze. Es ist daher notwendig, in der Notify-Prozedur den "Sender" des Events zu ermitteln. Tja, und da hab' ich im Augenblick keine Ahnung wie ich an diese Information herankomme?
TrzGridList = class(TList)
public procedure Notify (Ptr:Pointer;Action:TListNotification); override; end; procedure TrzGridList.Notify(Ptr:Pointer;Action:TListNotification); begin case Action of lnAdded : ShowMessage('data added'); lnDeleted : ShowMessage('data deleted'); end // sehr schön, // aber welche Liste hat die Info nun gesendet? end; |
Re: Änderungen in TList verfolgen
Hallo,
Kann man den Sender nicht via TObject(Ptr) ermitteln? |
Re: Änderungen in TList verfolgen
Moin toms,
der übergebene Pointer ist der Zeiger auf das z.B. an TList.Add() übergebene Datenobjekt :cry: |
Re: Änderungen in TList verfolgen
Bauingenieure sind ja für pragmatische, nicht unbedingt elegante Lösungen bekannt. Für die Eleganz sind die Architekten zuständig:
2 notwendige Listen > 2 individuelle Ableitungen von TList > jede Liste erhält damit ein eigenes Notify(). Passt! Problem beseitigt! |
Re: Änderungen in TList verfolgen
Du hast beide Listen und du hast 2 Member die jeweils eine Instanz halten. Warum vergleichst du somit nicht einfach die Listeninstanzen?
|
Re: Änderungen in TList verfolgen
Moin Roachford.
Nun genau das war mein Ansinnen. Es fehlt mir allerdings der konkrete Ansatz dies zu tun. Habe ein "Self.InstanceSize()" gefunden, aber kein "Self.InstanceName()". Mit welchem Kriterium bzw. Attribut kann ich also die beiden Instanzen unterscheiden? |
Re: Änderungen in TList verfolgen
Ich weiß nicht worauf du genau hinaus willst. Du könntest natürlich deiner Klasse TrzGridList noch eine Eigenschaft Name geben und diese im constructor setzen. Nur ich denke, das ist nicht der elegante Weg.
Edit: Anders gesagt: Was machst du im Notify, wenn du gerade nicht eine NAchricht anzeigen willst? |
Re: Änderungen in TList verfolgen
Delphi-Quellcode:
TListNotifyEvent = procedure(AList: TObject; const AAction: TListNotification; const AElement: TObject) of object;
TListDescendant = class(TList) private FOnNotify: TListNotifyEvent; protected procedure Notify(Ptr: Pointer; Action: TListNotification); override; public property OnNotify: TListNotifyEvent read FOnNotify write FOnNotify; end; ... procedure TListDescendant.Notify(Ptr: Pointer; Action: TListNotification); begin if assigned(FOnNotify) then FOnNotify(Self, Action, TObject(Ptr)); inherited; end;
Delphi-Quellcode:
Es gibt auch noch die Möglichkeit, dass die Liste direkt wissen von TMyGrid hat und direkt von diesem z.B. eine Methode aufruft über das friend-Verhalten innerhalb der Unit, aber das ist zum einen schlechter Stil und zum anderen kann man dann schlecht erweitern, also mal ein abgeleitetes TMyGrid einsetzen etc. Da sind die Eventhandler deutlich flexibler und es werden keine OOP Konzepte eingerissen (wie bei Friend-Prinzip) - ausser natürlich durch die Closure's an sich, welche CodeGear genau dazu eingeführt hat.
TMyGrid = class(TCustomGrid)
private fFilteredList: TListDescendant; fOtherList: TListDescendant; protected Procedure ListNotifier(AList: TObject; const AAction: TListNotification; const AElement: TObject); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; ... constructor TMyGrid.Create(AOwner: TComponent); begin inherited; fFilteredList := TListDescendant.Create; fFilteredList.OnNotify := ListNotifier; fOtherList := TListDescendant.Create; fOtherList.OnNotify := ListNotifier; end; destructor TMyGrid.Destroy; begin fFilteredList.Free; fOtherList.Free; inherited; end; procedure TMyGrid.ListNotifier(AList: TObject; const AAction: TListNotification; const AElement: TObject); begin if AList = fFilteredList then // gefilterte Liste else if AList = fOtherList then // die andere Liste ODER Liste := TListDescendant(AList); end; |
Re: Änderungen in TList verfolgen
Hallo Roachford!
Ja, was soll ich sagen? Wenn es jetzt so mundgerecht von dir präsentiert wird, frage ich mich, warum ich nicht selbst darauf gekommen bin. Das naheliegenste ist doch tatsächlich eine eigene Name-Property der Liste. Die Verwendung eines zusätzlichen Listen-Events, welches dann die Information von Notify() weiterleitet und eine Auswertung des Absenders innerhalb des Grids ermöglicht - na klar! Diese Variante werde ich verwenden! Vielen herzlichen Dank für deine Bemühungen :hi: Zur Frage (von sirius): Derzeit benötige ich im Grid nur die Information, dass sich die Liste geändert hat. Dann wird darauf reagiert, dass ein ggf. gesetzter Filter oder eine vorgenommene Sortierung nicht mehr aktuell sind. Aber vielleicht steigen die Anforderungen ja noch, bin derzeit noch beim "gemütlichen basteln". |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz