![]() |
Re: Drag Drop ListView kurz vor Verzweifelung
Ich habe noch mal geschaut, einen Ansatz wie ich es schaffen könnte in den Fenster die stehen bleibenden Markierungen
zu entfernen habe ich jetzt nur das eigentliche "entfernen" der Markierung klappt nicht. Hier bei gehts wieder um mein Eigentliches Programm eine MDI Anwendung, aber im Grunde vergleichbar mit dem Testprojekt. Ich durchlaufe einfach alle Fenster und suche nach einem ListView im "Virtual-Mode". Jetzt fehlt nur noch der letzte schritt. Ich habs mit Invalidate, Refresh etc. probiert nix, die Markierung bleibt erhalten. Das einzigste was etwas gebracht hat war kurz ltv_List.Items.Count := 0 und dann wieder auf die korrekte Anzahl zu setzten. Jedoch bekomme ich dann nicht mehr hin einen Eintrag normal zumarkieren weil dann OnEndDrag ausgelöst wird und mir die Selektion entfernt. Und bei großen Listen würde wohl auch der Scrollbalken hin und her springen was auch nicht so toll wäre.
Delphi-Quellcode:
@marabu Gute Besserung ;-)
//Alle Fenster nach TListView komponenten durchsuchen
For i := 0 To frmMain.MDIChildCount-1 Do Begin For z := 0 To frmMain.MDIChildren[i].ComponentCount-1 Do Begin If frmMain.MDIChildren[i].Components[z] Is TListView Then Begin With TListView(frmMain.MDIChildren[i].Components[z]) Do Begin If OwnerData Then Begin //Die richtige Selektion stehen lassen und die Artefakte entfernen... End; End;{with} End;{if} End;{for} End;{for} mfg TUX |
Re: Drag Drop ListView kurz vor Verzweifelung
Ich habe meinen Vorherigen Quelltext noch mal überarbeitet und jetzt eine etwas "unsaubere" Lösung gefunden wie ich finde.
Lass mich gerne korregieren bzw. verbessern, nur ist mir nichts anderes eingefallen wie es funktionieren könnte.
Delphi-Quellcode:
Meine Lösung macht jetzt folgendes es wird geschaut welche Einträge ausgewählt wurden, dann wird ebenfalls gemerkt wo der
//Alle Fenster nach TListView komponenten durchsuchen
For i := 0 To frmMain.MDIChildCount-1 Do Begin For z := 0 To frmMain.MDIChildren[i].ComponentCount-1 Do Begin If frmMain.MDIChildren[i].Components[z] Is TListView Then Begin With TListView(frmMain.MDIChildren[i].Components[z]) Do Begin If OwnerData Then Begin //Merken der Selektion sowie Scroll-Position SetLength(Sel, SelCount); Idx := 0; For c := 0 To Items.Count-1 Do Begin If Items[c].Selected Then Begin Sel[Idx] := c; Inc(Idx); End; End;{for} TopIt := TopItem.Index; //Reset der Listenelemente Count := Items.Count; Items.Count := 0; Items.Count := Count; //Widerherstellen der Selektion sowie Scroll-Position For c := 0 To High(Sel) Do Begin Items[Sel[c]].Selected := True; End; //ShowMessage(fGetField(Scroller[TopIt], 'Ident')); While (TopIt > TopItem.Index) Do Scroll(0, 10); End; End;{with} End;{if} End;{for} End;{for} Scrollbalken steht bzw. welcher Eintrag als erstes Sichtbar ist. Dann wird die Liste gelöscht und gleich neu geladen. Anschliessend werden die Einträge die zuvor markiert waren wieder markiert und die Liste wird an die ursprüngliche Position gescrollt. mfg TUX |
Re: Drag Drop ListView kurz vor Verzweifelung
Hallo TUX,
ich glaube meine grauen Zellen arbeiten schon wieder besser. Ich habe mit dem Aufruf der folgenden Prozedur im Ereignis OnEndDrag() gute Erfolge erzielt:
Delphi-Quellcode:
Ich habe mich gefragt, warum dein Problem bei virtuellen ListViews verschwindet, wenn das Ereignis OnDragDrop() ausgelöst wird. Den VCL-Autoren war aufgefallen, dass die Nachricht LVM_GetNextItem von virtuellen ListViews nicht erwartungsgemäß verarbeitet wird. Sie behandeln allerdings nur den ordnungsgemäß beendeten Drag-Vorgang, ein Abbruch bleibt unbehandelt. Das Testen überlasse ich dir.
procedure ResetDropHighlight(lv: TListView);
var i: Integer; begin with lv do for i := 0 to VisibleRowCount do if i >= Items.Count then Exit else if Items[TopItem.Index + i].DropTarget then begin Items[TopItem.Index + i].DropTarget := False; Exit; end end; Freundliche Grüße |
Re: Drag Drop ListView kurz vor Verzweifelung
Juhu es Funktioniert, also nach den ersten Test scheit es jetzt zu funktionieren wie es soll.
Hier noch mal der Quellcode:
Delphi-Quellcode:
Es werden alle Fenster durchlaufen und nach einem virtuellen ListView gesucht und dort die fehlerhaften Markierungen entfernt.
procedure Tfrm_Parts_List.pResetDropHighlight(lv: TListView);
var i: Integer; begin with lv do for i := 0 to VisibleRowCount-1 do if i >= Items.Count then Exit else if Items[TopItem.Index + i].DropTarget then begin Items[TopItem.Index + i].DropTarget := False; Exit; end end; procedure Tfrm_Parts_List.ltv_ListEndDrag(Sender, Target: TObject; X, Y: Integer); var i,z : Integer; begin //Alle Fenster nach TListView komponenten durchsuchen For i := 0 To frmMain.MDIChildCount-1 Do Begin For z := 0 To frmMain.MDIChildren[i].ComponentCount-1 Do Begin If frmMain.MDIChildren[i].Components[z] Is TListView Then Begin With TListView(frmMain.MDIChildren[i].Components[z]) Do Begin If OwnerData Then Begin pResetDropHighlight(TListView(frmMain.MDIChildren[i].Components[z])); End; End;{with} End;{if} End;{for} End;{for} end; Ich hatte zwar schon mal die Eigenschaft DropTarget entdeckt konnte damit aber nicht so recht was mit anfangen. Also noch mals vielen Dank marabu. Ich denke das scheint eine gute Lösung zu sein, nicht mehr so brutal wie mein Ansatz ;-) mfg TUX Edit: In der Prozedure pResetDropHighlight war noch ein kleiner Fehler, der eine Zugriffsverletztung herbei geführt hat und zwar muß es VisibleRowCount-1 heißen, da sonst das Ereignis OnData ein Item zeichnen will was nicht existiert. |
Re: Drag Drop ListView kurz vor Verzweifelung
Zitat:
Freundliche Grüße |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:16 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