Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Löschen einer Zeile mit anschließendem Aufrücken (https://www.delphipraxis.net/124267-loeschen-einer-zeile-mit-anschliessendem-aufruecken.html)

MaToBe 17. Nov 2008 18:11


Löschen einer Zeile mit anschließendem Aufrücken
 
Hallo liebe DPler,

Dies ist mein Code:
Delphi-Quellcode:
//Bilder laden
procedure TForm1.btnBildLadenClick(Sender: TObject);
begin
  if openPictureD.Execute then
  begin
    imgBild.Picture.LoadFromFile(openPictureD.FileName);
    sgDaten.Cells[0,clbBilder.Count] := inttostr(clbBilder.Count);
    sgDaten.Cells[1,clbBilder.Count] := ExtractFileName(openPictureD.FileName);
    sgDaten.Cells[2,clbBilder.Count] := ExtractFilePath(openPictureD.FileName) + ExtractFileName(openPictureD.FileName);
    clbBilder.Items.Add(ExtractFileName(openPictureD.FileName));
    lbBildName.Caption := ExtractFileName(openPictureD.FileName);
    lbBildpfad.Caption := ExtractFilePath(openPictureD.FileName) + ExtractFileName(openPictureD.FileName);
  end;
end;

//Bilder löschen
procedure TForm1.btnBildloeschenClick(Sender: TObject);
var ClickIndex : integer;
begin
    ClickIndex := clbBilder.ItemIndex;
    imgBild.Free;
    lbBildName.Caption := '';
    lbBildPfad.Caption := '';

    sgDaten.Rows[ClickIndex].Clear;
    for I := ClickIndex to sgDaten.RowCount-1 do
    begin
        sgDaten.Rows[i] := sgDaten.Rows[i+1];
    end;

    clbBilder.Items.Delete(ClickIndex);
end;

//Bilder anzeigen
procedure TForm1.clbBilderClick(Sender: TObject);
var ClickIndex : integer;
    BildPfad : string;
    BildName : string;
begin
    ClickIndex := clbBilder.ItemIndex;
    BildPfad :=  sgDaten.Cells[2,ClickIndex];
    BildName :=  sgDaten.Cells[1,ClickIndex];

    imgBild.Picture.LoadFromFile(BildPfad);
    lbBildName.Caption := BildName;
    lbBildpfad.Caption := BildPfad;
end;
Und dies ist mein Problem:
Ich habe eine CheckListBox, in der alle geladenen Bilder mit Namen stehen. Zusetzlich wird der Name des Bildes in einem StringGrit in der 2. Spalte und der Pfad in der 3. Spalte gespeichert. Klickt man nun auf einen Namen in der CheckListBox taucht das Bild auf. All das klappt gut.

Wenn ich ein Bild aus dem Verzeichnis löschen will, wird die ganze Zeile aus dem StingGrit gelöscht. Desweiteren werden alle nachfolgenden Zeileninhalte um eins nach oben gesetzt, so dass keine Lücke entsteht. Außerdem wird der Eintrag in der CheckListBox gelöscht. Leider taucht nun, wenn ich jetzt wieder ein Bild in der CheckListBox markiere um es anzuzeigen, ein Fehler auf: "Exception-Klasse EAccessViolation mit Meldung 'Zugriffsverletzung bei Adresse 004AF7F7 in Modul". :wiejetzt:

Ich hoffe das mir jemand erklären kann, wo der Fehler liegt und was ich da falsch gedacht habe.

Vielen Dank schonmal für eure Hilfe auch bei meinen anderen Fragen :dp:

Chemiker 17. Nov 2008 18:37

Re: Löschen einer Zeile mit anschließendem Aufrücken
 
Hallo MaToBe,

an welcher Stelle wird die Zeile den in Stringggrid gelöscht?

Bis bald Chemiker

MaToBe 17. Nov 2008 18:55

Re: Löschen einer Zeile mit anschließendem Aufrücken
 
Delphi-Quellcode:
//Bilder laden
procedure TForm1.btnBildLadenClick(Sender: TObject);
begin
  if openPictureD.Execute then
  begin
    imgBild.Picture.LoadFromFile(openPictureD.FileName);
    sgDaten.Cells[0,clbBilder.Count] := inttostr(clbBilder.Count);
    sgDaten.Cells[1,clbBilder.Count] := ExtractFileName(openPictureD.FileName);
    sgDaten.Cells[2,clbBilder.Count] := ExtractFilePath(openPictureD.FileName) + ExtractFileName(openPictureD.FileName);
    clbBilder.Items.Add(ExtractFileName(openPictureD.FileName));
    lbBildName.Caption := ExtractFileName(openPictureD.FileName);
    lbBildpfad.Caption := ExtractFilePath(openPictureD.FileName) + ExtractFileName(openPictureD.FileName);
  end;
end;

//Bilder löschen
procedure TForm1.btnBildloeschenClick(Sender: TObject);
var ClickIndex : integer;
begin
    ClickIndex := clbBilder.ItemIndex;
    imgBild.Free;
    lbBildName.Caption := '';
    lbBildPfad.Caption := '';

    sgDaten.Rows[ClickIndex].Clear;                               //Rot markieren ging nicht, Hier wird gelöscht ?!?
    for I := ClickIndex to sgDaten.RowCount-1 do
    begin
        sgDaten.Rows[i] := sgDaten.Rows[i+1];
    end;[/color]

    clbBilder.Items.Delete(ClickIndex);
end;

//Bilder anzeigen
procedure TForm1.clbBilderClick(Sender: TObject);
var ClickIndex : integer;
    BildPfad : string;
    BildName : string;
begin
    ClickIndex := clbBilder.ItemIndex;
    BildPfad :=  sgDaten.Cells[2,ClickIndex];
    BildName :=  sgDaten.Cells[1,ClickIndex];

    imgBild.Picture.LoadFromFile(BildPfad);
    lbBildName.Caption := BildName;
    lbBildpfad.Caption := BildPfad;
end;
Beim Rot markierten wird die betreffende Zeile gelöscht und der Rest eine Zeile nach oben verschoben oder?

€: Rot markieren ging nicht, kommentar beachten.

Hawkeye219 17. Nov 2008 19:19

Re: Löschen einer Zeile mit anschließendem Aufrücken
 
Hallo,

der Zugriffsfehler entsteht dadurch, dass du das (interne) Bild der TImage-Komponente freigibst. Beim nächsten Zugriff auf imgBild ist der Zeiger dann ungültig.

Wenn du das Bild löschen möchtest, dann geht das so:

Delphi-Quellcode:
imgBild.Picture := nil;
Gruß Hawkeye

MaToBe 17. Nov 2008 19:28

Re: Löschen einer Zeile mit anschließendem Aufrücken
 
jetzt klappts, danke ;)

da wär ich nie drauf gekommen :dp:

Hobby-Programmierer 17. Nov 2008 19:31

Re: Löschen einer Zeile mit anschließendem Aufrücken
 
Hallo ..., hier noch eine schnellere Variante um einzelne Zeilen im SG zu löschen. Du brauchst dich dann nimmer um das 'Nachrücken' der Zeilen kümmern!
Delphi-Quellcode:
type
  TStringGridHack = class(TStringGrid)
  protected
    procedure DeleteRow(ARow: Longint); reintroduce;
  end;

...

//---------- HackGrid ---------
//--- Zeile löschen
procedure TStringGridHack.DeleteRow(ARow: Longint);
var GemRow: Integer;
begin
  GemRow := Row;
  if RowCount > FixedRows + 1 then
    inherited DeleteRow(ARow)
  else
    Rows[ARow].Clear;
  if GemRow < RowCount then
    Row := GemRow;
end;


[Edit] hab gefunden woher ich den Code mal her hatte
 [url=http://swissdelphicenter.ch/de/showcode.php?id=460]Link[/url]


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:49 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