Delphi-PRAXiS
Seite 4 von 4   « Erste     234   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi ListView mit OwnerData schneller machen? (https://www.delphipraxis.net/179644-listview-mit-ownerdata-schneller-machen.html)

OrNEC 23. Mär 2014 21:12

AW: ListView mit OwnerData schneller machen?
 
Zitat:

Zitat von sx2008 (Beitrag 1253167)
Zitat:

Zitat von OrNEC (Beitrag 1253095)
Der Zugriff erfolgt über SQLiteSimpleDelphi-Wrappers von Tim Anderson.

Tja - das ist leider keine Ableitung von TDataset.
Damit können die datensensitiven Komponenten nicht angebunden werden.
Für kleine Projekte kann man sich auch so behelfen aber wenn's etwas mehr wird (> 3 Tabellen) braucht man "richtige" Komponenten.

Welche kannst Du für SQLite empfehlen?

Sir Rufo 25. Mär 2014 11:13

AW: ListView mit OwnerData schneller machen?
 
Liste der Anhänge anzeigen (Anzahl: 2)
Weil das mit den Generics und Anonymen Methoden so schön geht, habe ich hier mal eine kleine Virtual-ListView Demo gemacht.

Vom Start weg erzeugt die 100.000 zufällige Personen, die dann noch bearbeitet/gelöscht/hinzugefügt werden können.
Der größte Zeitfresser ist hier die Sortierung, was aber auch nichts macht, da ich die Aktionen (anlegen, speichern, sortieren) im Hintergrund ausführen lasse und der Anwender so lange eine modale Form angezeigt bekommt, damit dem nicht langweilig wird ;)

Evtl. kann das hier ja als Anregung dienen.

Achtung: Das Beispiel ist nur unter den aktuelleren Delphis (ab XE3?) lauffähig (im Anhang befindet sich auch eine kompilierte Version)

Haupt-Form:
Delphi-Quellcode:
unit UI_Form_Main;

interface

uses
  Winapi.Windows, Winapi.Messages,
  System.Generics.Collections, System.Actions, System.SysUtils, System.Variants,
  System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls,
  Vcl.StdCtrls, Vcl.ActnList, Vcl.ExtCtrls,
  UI_Form_Base,
  Model_Person;

type
  TMainForm = class( TBaseForm )
    Persons_ListView : TListView;
    NewPerson_Button : TButton;
    EditPerson_Button : TButton;
    ActionList1 : TActionList;
    NewPerson_Action : TAction;
    EditPerson_Action : TAction;
    Action_Panel : TPanel;
    DeletePerson_Action : TAction;
    DeletePerson_Button : TButton;
    procedure Persons_ListViewData( Sender : TObject; Item : TListItem );
    procedure Persons_ListViewEdited( Sender : TObject; Item : TListItem; var S : string );
    procedure Persons_ListViewChange( Sender : TObject; Item : TListItem; Change : TItemChange );
    procedure NewPerson_ActionExecute( Sender : TObject );
    procedure EditPerson_ActionExecute( Sender : TObject );
    procedure EditPerson_ActionUpdate( Sender : TObject );
    procedure DeletePerson_ActionUpdate( Sender : TObject );
    procedure DeletePerson_ActionExecute( Sender : TObject );
  private
    { Person-ID Generator }
    FNextPersonId : Integer;
    function GetNextPersonId : Integer;
  private
    { Model }
    FPersons : TList<TPerson>;
    FCurrentPersonIndex : Integer;
    function GetCurrentPerson : TPerson;
    procedure SetCurrentPerson( const Value : TPerson );
  protected
    { Binding }
    procedure DoLoadFromModel; override;
    procedure DoSaveToModel; override;
  private
    { Background }
    procedure DoCreateSomePersons( Count : Integer );
    procedure DoSave( Person : TPerson );
    procedure DoSort;
  private
    { Facade Methods }
    function EditPerson( Person : TPerson ) : TPerson;
    procedure CreateSomePersons( Count : Integer );
    procedure SaveAndSort( Person : TPerson );
  public
    { Facade }
    procedure AddNewPerson;
    procedure EditCurrentPerson;
    procedure DeleteCurrentPerson;
  public
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
  public
    property CurrentPerson : TPerson read GetCurrentPerson write SetCurrentPerson;
  end;

var
  MainForm : TMainForm;

implementation

{$R *.dfm}

uses
  System.DateUtils,
  UI_Form_Person_Edit,
  UI_Form_BackgroundWorker;

{ TMainForm }

procedure TMainForm.AddNewPerson;
begin
  CreateSomePersons( 1 );
  LoadFromModel;
end;

procedure TMainForm.AfterConstruction;
begin
  inherited;
  FPersons := TObjectList<TPerson>.Create( TPerson.EqualityComparer );
  FCurrentPersonIndex := FPersons.Count - 1;

  CreateSomePersons( 100000 );
  LoadFromModel;
end;

procedure TMainForm.BeforeDestruction;
begin
  inherited;
  FPersons.Free;
end;

procedure TMainForm.NewPerson_ActionExecute( Sender : TObject );
begin
  inherited;
  AddNewPerson;
end;

function TMainForm.EditPerson( Person : TPerson ) : TPerson;
var
  LPersonEdit : TEditPersonForm;
begin
  if Assigned( Person )
  then
  begin
    LPersonEdit := TEditPersonForm.Create( nil );
    try
      LPersonEdit.Person := Person;
      if LPersonEdit.ShowModal = mrOk
      then
      begin
        SaveAndSort( LPersonEdit.Person );
      end;
    finally
      LPersonEdit.Free;
    end;
  end;
  Result := Person;
end;

procedure TMainForm.EditPerson_ActionExecute( Sender : TObject );
begin
  inherited;
  EditCurrentPerson;
end;

procedure TMainForm.EditPerson_ActionUpdate( Sender : TObject );
begin
  inherited;
  ( Sender as TAction ).Enabled := Assigned( CurrentPerson );
end;

procedure TMainForm.CreateSomePersons( Count : Integer );
var
  LPerson : TPerson;
begin
  DoCreateSomePersons( Count );
  LPerson := FPersons.Last;
  DoSort;
  CurrentPerson := LPerson;
end;

procedure TMainForm.DeleteCurrentPerson;
begin
  if Assigned( CurrentPerson )
  then
  begin
    FPersons.Remove( CurrentPerson );
    Dec( FCurrentPersonIndex );
  end;
  LoadFromModel;
end;

procedure TMainForm.DeletePerson_ActionExecute( Sender : TObject );
begin
  inherited;
  DeleteCurrentPerson;
end;

procedure TMainForm.DeletePerson_ActionUpdate( Sender : TObject );
begin
  inherited;
  ( Sender as TAction ).Enabled := Assigned( CurrentPerson );
end;

procedure TMainForm.DoCreateSomePersons( Count : Integer );
begin
  PerformInBackground(
      procedure
    var
      LPerson : TPerson;
      LIdx : Integer;
    begin
      for LIdx := 1 to Count do
      begin
        LPerson := TPerson.Create( GetNextPersonId );
        try
          LPerson.Firstname := C_FIRSTNAMES[Random( Length( C_FIRSTNAMES ) )];
          LPerson.Lastname := C_LASTNAMES[Random( Length( C_LASTNAMES ) )];
          LPerson.DisplayAs := LPerson.Lastname + ', ' + LPerson.Firstname;
          LPerson.DOB := Date - ( Random( 365 * 60 ) + 18 * 365 );
          FPersons.Add( TPerson.Create( LPerson ) );
        finally
          LPerson.Free;
        end;
      end;
    end, Format( 'Erzeuge %d Einträge...', [Count] ) );
end;

procedure TMainForm.DoLoadFromModel;
begin
  inherited;
  // Anzahl der Einträge festlegen
  Persons_ListView.Items.Count := FPersons.Count;
  // Aktuelle Auswahl festlegen
  Persons_ListView.ItemIndex := FCurrentPersonIndex;
  // sieht komisch aus, ist aber notwendig damit der aktuelle Eintrag auch
  // sichtbar wird
  Persons_ListView.Items.Count := FPersons.Count;
  // Falls Änderungen an den Daten vorgenommen wurden, einfach mal neuzeichnen lassen
  Persons_ListView.Invalidate;
end;

procedure TMainForm.DoSave( Person : TPerson );
begin
  PerformInBackground(
    procedure
    begin
      if FPersons.Contains( Person )
      then
        FPersons[FPersons.IndexOf( Person )].Assign( Person )
      else
        FPersons.Add( TPerson.Create( Person ) );
    end, Format( 'Speichern von %s', [Person.ToString] ) );
end;

procedure TMainForm.DoSaveToModel;
begin
  inherited;
  FCurrentPersonIndex := Persons_ListView.ItemIndex;
end;

procedure TMainForm.DoSort;
begin
  PerformInBackground(
    procedure
    begin
      FPersons.Sort( TPerson.SortComparer );
    end, Format( 'Sortiere %d Einträge...', [FPersons.Count] ) );
end;

procedure TMainForm.EditCurrentPerson;
begin
  CurrentPerson := EditPerson( CurrentPerson );
  LoadFromModel;
end;

function TMainForm.GetCurrentPerson : TPerson;
begin
  if FCurrentPersonIndex < 0
  then
    Result := nil
  else
    Result := FPersons[FCurrentPersonIndex];
end;

function TMainForm.GetNextPersonId : Integer;
begin
  Result := FNextPersonId;
  Inc( FNextPersonId );
end;

procedure TMainForm.Persons_ListViewChange( Sender : TObject; Item : TListItem; Change : TItemChange );
begin
  inherited;
  SyncWithModel;
end;

procedure TMainForm.Persons_ListViewData( Sender : TObject; Item : TListItem );
var
  LPerson : TPerson;
begin
  inherited;
  LPerson := FPersons[Item.Index];
  Item.Caption := LPerson.ToString;
  Item.SubItems.Add( LPerson.Lastname );
  Item.SubItems.Add( LPerson.Firstname );
  Item.SubItems.Add( DateToStr( LPerson.DOB ) );
  Item.SubItems.Add( IntToStr( YearsBetween( Date, LPerson.DOB ) ) );
end;

procedure TMainForm.Persons_ListViewEdited( Sender : TObject; Item : TListItem; var S : string );
var
  LPerson : TPerson;
begin
  inherited;
  LPerson := TPerson.Create( FPersons[Item.Index] );
  try
    if LPerson.DisplayAs <> S
    then
    begin
      LPerson.DisplayAs := S;
      EditPerson( LPerson );
      CurrentPerson := LPerson;
    end;
  finally
    LPerson.Free;
  end;
end;

procedure TMainForm.SaveAndSort( Person : TPerson );
begin
  DoSave( Person );
  DoSort;
end;

procedure TMainForm.SetCurrentPerson( const Value : TPerson );
begin
  if not Assigned( Value )
  then
    FCurrentPersonIndex := - 1
  else
    FCurrentPersonIndex := FPersons.IndexOf( Value );
  LoadFromModel;
end;

end.

Zoot 25. Mär 2014 11:47

AW: ListView mit OwnerData schneller machen?
 
Ich bekomme eine Warnung "Behav_214-Trojaner" bei der Zip-Datei.

AlexII 25. Mär 2014 12:01

AW: ListView mit OwnerData schneller machen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Zoot (Beitrag 1253404)
Ich bekomme eine Warnung "Behav_214-Trojaner" bei der Zip-Datei.

Irgendwas stimmt mit deinem Virenscanner nicht.

Zoot 25. Mär 2014 12:03

AW: ListView mit OwnerData schneller machen?
 
SonicWALL Gateway Anti-Virus Service. Ich komm da hier nicht ran.

Sir Rufo 25. Mär 2014 12:06

AW: ListView mit OwnerData schneller machen?
 
Zitat:

Zitat von AlexII (Beitrag 1253406)
Zitat:

Zitat von Zoot (Beitrag 1253404)
Ich bekomme eine Warnung "Behav_214-Trojaner" bei der Zip-Datei.

Irgendwas stimmt mit deinem Virenscanner nicht.

Und ich wundere mich gerade schon, warum die Datei da schon gescannt sein soll ;)

Sir Rufo 25. Mär 2014 12:09

AW: ListView mit OwnerData schneller machen?
 
Ich habe das jetzt zusätzlich noch mal als .7z angehängt.
Auch da meldet VirusTotal keine Befunden

Zoot 25. Mär 2014 12:33

AW: ListView mit OwnerData schneller machen?
 
Sonic Wall auch nicht mehr.
Danke!


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:31 Uhr.
Seite 4 von 4   « Erste     234   

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