Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   DBGrid Zeilen Wechsel (https://www.delphipraxis.net/177928-dbgrid-zeilen-wechsel.html)

Andidreas 6. Dez 2013 11:56

Datenbank: SQLite • Version: ... • Zugriff über: UniDac

DBGrid Zeilen Wechsel
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

in meinem DBGrid bekomm ich ja über die Ereignisse OnCellClick, OnKeyUp, OnMouseWheel mit ob sich die Zeile gewechselt hat...

Wenn jetzt aber ein User auf die ganz Linke Spalte klickt (wo keine Daten drin stehn [siehe Bild]) bekomm ich es nicht mit das sich die Zeile geändert hat...
Kann man das irgendwie abfangen, geht das über das TDBGrid oder muss ich von dem hinterlegtn Datasource oder Query ein Ereignis nehmen?

bcvs 6. Dez 2013 12:04

AW: DBGrid Zeilen Wechsel
 
Zitat:

Zitat von Andidreas (Beitrag 1238765)
oder muss ich von dem hinterlegtn Datasource oder Query ein Ereignis nehmen?

Ja, das wäre besser. Dafür nimmt man das OnAfterScroll des Query bzw. Table.

Dann ist es auch egal, wie der Benutzer die Zeile wechselt (Mausklick, Mauswheel, Tastatur).

Andidreas 6. Dez 2013 12:09

AW: DBGrid Zeilen Wechsel
 
Ok, den Klick auf den linken Rand des DBGrids bekomm ich dann auch mit?

Perlsau 6. Dez 2013 12:33

AW: DBGrid Zeilen Wechsel
 
Zitat:

Zitat von Andidreas (Beitrag 1238767)
Ok, den Klick auf den linken Rand des DBGrids bekomm ich dann auch mit?

AfterScroll bedeutet "nach dem Scrollen", Scroll bedeutet Bildlauf und rührt vom früher gebräuchlichen Drehen der Buchrolle bei antiken Büchern, die aufgerollt waren, her. Das Wechseln des Datensatzes (Scrolling, auch bekannt als Ändern des Datensatz-Zeigers) löst das Ereignis AfterScroll aus. Dabei ist es völlig egal, wie der Scrollvorgang ausgelöst wurde. Wenn der genannte Klick also zu einem Scrolling führt, dann wird AfterScroll ausgelöst.

PMM 6. Dez 2013 13:14

AW: DBGrid Zeilen Wechsel
 
Aber Vorsicht, bei OnScroll ist es, wie Perlsau sagte "völlig egal, wie der Scrollvorgang ausgelöst wurde". Die müssen somit gar nicht vom DBGrid kommen und das war eigentlich das was Andidreas wollte....

Perlsau 6. Dez 2013 15:05

AW: DBGrid Zeilen Wechsel
 
1. Da beim Klick auf die linke äußere Spalte, die gewöhnlich als Indikator für den Datensatzzeiger dient, offenbar kein OnClick-Ereignis auslöst, muß man zwangsläufig mit der Datenquelle arbeiten. @Andidreas: Überprüfe doch mal, ob nicht vielleicht ein OnChange oder was Ähnliches ausgelöst wird. Wäre meiner Ansicht aber dennoch der falsche Weg.

2. Wenn irgend eine andere Komponente einen Wechsel des Datensatz-Zeigers auslöst, wird das auch im DBGrid zu sehen sein, denn das reagiert ja darauf. Es ist Sache des Entwicklers, zu verhindern, daß andere Komponenten einen Datensatzwechsel durchführen, wenn das nicht gewünscht ist.

3. Will man dafür sorgen, daß bestimmte Befehle nur dann abgearbeitet werden, wenn der Datensatzwechsel vom DBGrid ausgelöst wurde, prüft man in der Ereignisbehandlung – was ich für richtiger halte – einfach auf DBGrid.Focused.

Andidreas 9. Dez 2013 09:47

AW: DBGrid Zeilen Wechsel
 
Das Problem habe ich gerade in einer DLL...
Die Query Komponente habe ich hier nicht auf der Form liegen, sondern die Komponente wird beim Start der DLL erstellt...

Code:
Delphi-Quellcode:
    If SQLiteFileConnection.Connected Then
    Begin
      SQLiteFile_Query1 := TUniQuery.Create(nil);
      SQLiteFile_Query1.Connection := SQLiteFileConnection;
      SQLiteFile_DisplayCommissions := TUniQuery.Create(nil);
      SQLiteFile_DisplayCommissions.Connection := SQLiteFileConnection;
    End;
Wie kann ich hier auf dieses Ereignis Abfragen?

sx2008 9. Dez 2013 10:19

AW: DBGrid Zeilen Wechsel
 
Zitat:

Zitat von Andidreas (Beitrag 1239070)
Das Problem habe ich gerade in einer DLL...
Die Query Komponente habe ich hier nicht auf der Form liegen, sondern die Komponente wird beim Start der DLL erstellt...

Du weisst aber dass eine normale DLL keine objektorientierte Schnittstelle hat?!
Deshalb kann man Delphi-Events nicht über eine DLL-Grenze transportieren.
(Man kan evtl. schon, aber mit so hohem Aufwand und hässlichem Rumgemache dass es keinen Sinn ergibt)

Eine Anwendung besteht aus Code der sich häufig ändert (die Businesslogik) und Code der sich fast nie ändert (z.B. irgendwelche Bibliotheken).
Einer der größten Fehler den man in Delphi machen kann ist die Businesslogik aufzutrennen und in Exe und DLLs zu splitten.
In C# sieht das ganz anderst aus, aber in Delphi wird man damit nicht glücklich.

Ich versuch das mal mit einer Analogie zu verdeutlichen:
Stell dir vor du hast eine Elektronikplatine mit vielen Bauteilen und sägst sie mitten auseinander.
Die beiden Teilplatinen werden nun durch einzelne dünne Kabel mit 1 Meter Länge verbunden.
Ok, die Gesamtelektronik funktioniert noch ist aber viel teurer geworden.
Jetzt soll die elektronische Schaltung erweitert werden und so werden die vielen Leitungsverbindungen zur echten Falle.

Und jetzt vergleiche das mal mit einem PC-Motherboard und ihren PCI-Steckplätzen.
Die PCI-Schnittstelle ist genormt und nur deshalb funktioniert das Stecksystem.

Und daher: niemals die Businesslogik auseinandereisen wenn es nicht von der Programmiersprache perfekt unterstützt wird oder grundsätzlich eine Multi-Tier-Anwendung entstehen soll.

Andidreas 9. Dez 2013 10:30

AW: DBGrid Zeilen Wechsel
 
Ich weiß nicht ob ich das richtig rübergebracht habe...

Ich möchte nicht das Event von einer Exe in eine DLL transportieren!
Ich habe eine DLL die eine komplette eigenständige Funktion abdeckt... nehmen wir als Beispiel eine User Verwaltung für eine Software...
D.h. Ich hole mir in der DLL die Daten, zeige sie an und möchte sie dort auch verändern können...

Damit ich jetzt genau weiß auf welchem User ich sitze möchte ich das AfterScroll Ereigniss verwenden...

Die Query Komponente erstelle ich deshalb dynamisch, da die diversen DB Verbindungen von der Exe an die DLL mit übergeben werden!

baumina 9. Dez 2013 10:34

AW: DBGrid Zeilen Wechsel
 
Du musst das Event einfach nur zuweisen ADataset.AfterScroll := xxprocedure und die Procedure dann schreiben xxprocedure(Sender : TDataset)

Andidreas 9. Dez 2013 10:36

AW: DBGrid Zeilen Wechsel
 
Zitat:

Zitat von baumina (Beitrag 1239075)
Du musst das Event einfach nur zuweisen ADataset.AfterScroll := xxprocedure und die Procedure dann schreiben xxprocedure(Sender : TDataset)

Also die Prozedur hatte ich schon im Source drinnen... Die wurde nur nie aufgerufen!

Wie funktioniert die Event zuweisung?

baumina 9. Dez 2013 10:40

AW: DBGrid Zeilen Wechsel
 
ADataset.AfterScroll := xxprocedure

Perlsau 9. Dez 2013 10:59

AW: DBGrid Zeilen Wechsel
 
Ergänzung zu Bauminas Hinweis: Die Zuweisung verhält sich analog zum Objektinspektor: Das Property AfterScroll erhält die Adresse deiner Procedure, indem du diese Procedure dem Property zuweist. Danach wird deine Procedure auch aufgerufen, wenn gescrollt wird. Wenn du im OI auf AfterScroll doppelt klickst, passiert genau dasselbe: Es wird ein Procedur-Rumpf erstellt und im OI eingetragen.

Einfach mal ausprobieren ...

Übrigens hatte Baumina diesen Hinweis bereits geliefert.

Andidreas 9. Dez 2013 12:37

AW: DBGrid Zeilen Wechsel
 
Ja den Hinweis von Baumina hab ich gelesen, aber ich hab sowas noch nie gemacht ;-) Deshalb meine Frage...

DeddyH 9. Dez 2013 12:42

AW: DBGrid Zeilen Wechsel
 
Es muss aber eine Methode sein, eine reguläre Prozedur lässt sich nicht zuweisen.

Andidreas 9. Dez 2013 12:50

AW: DBGrid Zeilen Wechsel
 
Also das folgende habe ich gemacht:

Delphi-Quellcode:

unit view;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, AdvGlowButton, Uni, StdCtrls, ShlObj, Grids, DBGrids, DB,
  MemDS, DBAccess;

type
  Tform = class(TForm)
    timerstart: TTimer;
    pnl_insertedit: TPanel;
    lbl_materialdescription: TLabel;
    lbl_tablecontent: TLabel;
    advglowbtn_search: TAdvGlowButton;
    advglowbtn_showall: TAdvGlowButton;
    edt_materialdescription: TEdit;
    dbgrid_data: TDBGrid;
    datsrc_data: TDataSource;
    procedure FormDestroy(Sender: TObject);
    procedure timerstartTimer(Sender: TObject);

    procedure SQLiteFile_DisplayAfterScroll(DataSet: TDataSet);

  private
    procedure prButtonandFieldControl(blLocked : Boolean);
    procedure prDisplayDESADVCommissionData(sCommissionNo, sDescription, sDSMin, sDSMax : String; blSearch : Boolean);
    procedure prDisplayDESADVCommissionDetails(sCommissionNo, sDSMin, sDSMax : String);
    procedure prGetDESADVCommissionMinMaxDS(sDESADVModule : String);
  public

  end;

.
.
.

procedure Tform.SQLiteFile_DisplayAfterScroll(DataSet: TDataSet);

begin

  If (gblViewCommissions) Then ShowMessage('New Record Selected');

end;
Mit diesem Source wird das AfterScroll nicht ausgelöst da das Event noch nicht zugewiesen ist, und da häng ich grad da ich nicht weiß wie sowas geht...

Perlsau 9. Dez 2013 12:53

AW: DBGrid Zeilen Wechsel
 
Wo weist du denn dem Property OnAfterScroll deines Datasets die Methode
Delphi-Quellcode:
Tform.SQLiteFile_DisplayAfterScroll(DataSet: TDataSet);
zu?

baumina 9. Dez 2013 13:02

AW: DBGrid Zeilen Wechsel
 
Also dann mal ausführlich zum Abschreiben:

Delphi-Quellcode:
procedure ErstelleDataset;
var
  aDataset : TDataset;

begin
  aDataSet := TDataset.Create;
  ...
  aDataset.AfterScroll := DoAferScroll;
  ...
end;

procedure DoAfterScroll(Sender : TDataset);
begin
 ...
end;

DeddyH 9. Dez 2013 13:19

AW: DBGrid Zeilen Wechsel
 
Das ist keine Methode, daher wird das so nicht funktionieren.

Andidreas 9. Dez 2013 13:29

AW: DBGrid Zeilen Wechsel
 
Schon mal vielen Dank Baumina! :thumb:

Ich weiß es wird hier im Forum nicht gern gesehen wenn man sich die Lösung vorkauen lässt ohne eigen Initiative.
Aber Ihr könnt mir glauben das ich gerade nicht vor meinem PC hocke und die ganze Zeit F5 drücke um auf Antworten zu warten... Habe nebenher auch Hr. Google bemüht aber irgendwie steh ich aufm Schlauch...

Nochmal von vorn...

Ich hab mir ein simples Programm zum Anzeigen von Daten gemacht.
Dort verwende ich das AfterScroll Ereignis der TUniQuery um den Wechsel von Daten Zeilen mitzubekommen und meine gewünschten Aktionen durchzuführen...
Funktioniert wunderbar...

In meiner DLL ist die vorgehensweise wie folgt...

Ich erstelle meine TUniQuery Komponente mit der ich die Daten von der DB abhole.
Mittlerweile habe ich mir die folgende Procedure angelegt die den Source beinhalten soll für das AfterScroll:
Delphi-Quellcode:
procedure Tform.prAfterScroll(Sender: TDataSet);

begin

  If (gblView) Then ShowMessage('New Record Selected');

end;
Nun versuche ich beim Laden der DLL der dynamisch erstellen TUniQuery im AfterScroll Ereignis meine Procedure zu zuweisen:

Versuch 1

Delphi-Quellcode:
  SQLiteFile_DisplayCommissions.DataSource.DataSet.AfterScroll := prAfterScroll(SQLiteFile_DisplayCommissions);

Versuch 2

Delphi-Quellcode:
  SQLiteFile_DisplayCommissions.AfterScroll := prAfterScroll(SQLiteFile_DisplayCommissions);

Beides mal kommt beim kompilieren die Fehlermeldung:
E2010 Inkompatible Typen: 'TDataSetNotifyEvent' und 'procedure, untyped pointer or untyped parameter'

Ich will niemand ärgern oder nerven, aber was das betrifft ist mein Wissen jungfräulich, ich hab noch nie eigene Events einer Komponente zugewiesen!

DeddyH 9. Dez 2013 13:31

AW: DBGrid Zeilen Wechsel
 
Lass mal die Klammern samt Parameterangabe weg.

Andidreas 9. Dez 2013 13:36

AW: DBGrid Zeilen Wechsel
 
Perfekt!

Vielen Dank an alle für die Hilfe!
Wieder was dazu gelernt :thumb:

baumina 9. Dez 2013 13:38

AW: DBGrid Zeilen Wechsel
 
Naja, spricht ja für dich, dass du wohl im Abschreiben in der Schule nicht so gut warst :-D

Andidreas 9. Dez 2013 13:50

AW: DBGrid Zeilen Wechsel
 
Zitat:

Zitat von baumina (Beitrag 1239123)
Naja, spricht ja für dich, dass du wohl im Abschreiben in der Schule nicht so gut warst :-D

OT:
Und wenn dann nicht sehr talentiert... Der Rektor hat mich in der Mathe Prüfung dabei erwischt :oops:

himitsu 9. Dez 2013 14:14

AW: DBGrid Zeilen Wechsel
 
Zitat:

Zitat von Andidreas (Beitrag 1238767)
Ok, den Klick auf den linken Rand des DBGrids bekomm ich dann auch mit?

Ja, wenn das Grid die DataSource/DataSet mit der Selektierung synchronisiert.

Einige Grids bieten da einen Modus, welcher das nicht macht,
wo also die selektierte fokusierte Zeile nicht mit dem aktuell selektierten Record übereinstimmt. (vorallem bei Multiselect manchmal so gewollt)
Und wo im Gegenzug ein Scrollen im Dataset auch nicht den Fokus im Grid beeinflusst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:37 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz