![]() |
Multiselect mit Strg + Maus (wie?)
Hallo,
um das mehrfache selektieren von Elementen zu unterstützen, dachte ich mir machst es wie allgemein üblich mit Strg+(linker)Maustaste. Doch nun nach einigen Versuchen, stellt sich die Frage: Wie macht man das? Das setzen eines Flags zum Beginn der Auswahl stellt nich das Problem dar, sondern eher die Hürde festzustellen wann ist die Auswahl beendet. Hat jemand Ideen bzw. ein Lösungsvorschlag? Gruss |
Re: Multiselect mit Strg + Maus (wie?)
ich versteh nicht so recht das Problem. Wird mit der Maus etwas angeklickt und die Strg-Taste ist nicht gedrückt, so wird das angeklickte selektiert und alles andere deselktiert. Ist die Strg-Taste gedrückt wird das deselektieren einfach weg gelassen.
|
Re: Multiselect mit Strg + Maus (wie?)
Das Problem ist, das nur bei gedrückter Strg-Taste mit der Maus selektiert wird und das ist bei jedem mir bekannten
Programmen so. Aber egal. Wenn ich also vereinfacht ausgedrückt mir ein Flag bastel welches beim ersten drücken der Maustaste, den Shiftstate auswertet und bei gedrückter Strg-Taste gesetzt wird.
Delphi-Quellcode:
Damit weiß ich also, der User will etwas Mehrfach auswählen und kann in MouseUp entsprechend reagieren.
...
iMultiSelect : Boolean; // fortlaufene Merhfachauswahl 1-10 mMultiSelect : Boolean; // manuelle Mehrfachauswahl 1, 3, 6, 12 usw. iButton : Boolean; // Auswahl mit linker Maustaste, wird zwischen gespeichert, // da in MouseMove kein Button übergeben wird ... procedure TCalendarControl.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin iButton := Button = mbLeft; if iButton and FOptions.MultiSelect and not mMultiSelect and (ssCtrl in Shift) then mMultiSelect := True; inherited; end;
Delphi-Quellcode:
Bis hierher funktioniert die Sache ja auch, die gewälten Elemente werden in die Liste FMultiSelect eingetragen.
procedure TCalendarControl.MouseUp(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); var I, J, FMin : Integer; begin iButton := False; if Button = mbLeft then begin if FWeekNumbers then FMin := 1 else FMin := 0; if iMultiSelect or mMultiSelect then begin if not (ssCtrl in Shift) and iMultiSelect then iMultiSelect := False; for J := 0 to FMaxWeeks do begin for I := FMin to FMax do begin if TCalenderEntry(FWeeks[J][I]).MouseInRect(X, Y) then begin if FMultiSelDates.IndexOf(TCalenderEntry(FWeeks[J][I])) = -1 then FMultiSelDates.Add(TCalenderEntry(FWeeks[J][I])); end; end; end; if iMultiSelect then DoMultiSelect(FMultiSelDates); Invalidate; end ... Erfolgt jedoch die Auswahl mit zusätzlich gedrückter Strg+Taste wird jedesmal bei der Auswahl mit der Maus KeyUP mitaufgerufen...
Delphi-Quellcode:
und das Flag mMultiSelect wird gelöscht, weil Shift(warum auch immer) kein ssCtrl mehr enthält.
procedure TCalendarControl.KeyUp(var Key: Word; Shift: TShiftState);
begin if mMultiSelect and not (ssCtrl in Shift) then mMultiSelect := False; inherited KeyUp(Key, Shift); end; Nun verstanden? |
Re: Multiselect mit Strg + Maus (wie?)
Zitat:
Klickt man etwas an wird es selektiert. Ist während des MouseDown die Strg-Taste nicht selektiert wird die vorherige Selektierung entfernt. Aber ich glaube ich versteh dein Problem nicht und wir reden aneinander vorbei. |
Re: Multiselect mit Strg + Maus (wie?)
So, So,
Zitat:
Ich kann sie auch auch gleich mit Strg+Maus auswählen(probier mal, aber nichts anderes vorher machen, auch kein Strg+A). Ansonsten schönen Tag noch. Gruss |
Re: Multiselect mit Strg + Maus (wie?)
das verhalten bleibt doch gleich (gerade probiert). Wenn man etwas anklickt ohne das Strg gedrückt ist wird nur das angeklickte Selektiert und alles andere was zu diesem Zeitpunkt eventuell selektiert war wird deselektiert. Ist Strg gedrückt wird die Selektierung des angeklickten negiert.
|
Re: Multiselect mit Strg + Maus (wie?)
@sirT: das funktioniert schon seit ewigkeiten. :wink:
dann lass doch die flag-rückstellung weg im onkeyup! imho brauchst du nicht ständig die strg-taste gedrückt halten. du kannst sie auch jedesmal vor der maustaste drücken. nur wenn du ohne strg-tste die mausaktion durchführst, dann wird die auswahl wieder aufgehoben und nur das eine element selektiert. vielleicht reicht das ja...
Delphi-Quellcode:
procedure TCalendarControl.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); begin iButton := Button = mbLeft; {if iButton and FOptions.MultiSelect and not mMultiSelect and (ssCtrl in Shift) then mMultiSelect := True; } // multiselekt nur true wenn zusätzlich auch ctrl gedrückt ansonsten false... mMultiSelect := iButton and FOptions.MultiSelect and not mMultiSelect and (ssCtrl in Shift); inherited; end; |
Re: Multiselect mit Strg + Maus (wie?)
Also ich hab mal fix eine Testkomponente programmiert und die funktioniert eigentlich Windowsüblich:
Delphi-Quellcode:
unit uExampleCtrl;
interface uses windows, classes, graphics, controls; type TExampleCtrl = class(TCustomControl) private fStati : Array[0..5] of Boolean; protected procedure Paint(); override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; public constructor Create(AOwner: TComponent); override; end; implementation { TExampleCtrl } constructor TExampleCtrl.Create(AOwner: TComponent); var lCount : Integer; begin inherited Create(AOwner); ZeroMemory(@fStati, SizeOf(fStati)); SetBounds(0, 0, 300, 300); end; procedure TExampleCtrl.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var lIndex : Integer; begin inherited; lIndex := X div (Width div 3) + Y div (Height div 2) * 3; if (ssCtrl in Shift) then fStati[lIndex] := not(fStati[lIndex]) else begin ZeroMemory(@fStati, SizeOf(fStati)); fStati[lIndex] := True; end; Invalidate(); end; procedure TExampleCtrl.Paint; var lCountX, lCountY, lIndex, lPartHeight, lPartWidth : Integer; begin lPartHeight := Height div 2; lPartWidth := Width div 3; Canvas.Brush.Color := clWhite; Canvas.FillRect(Rect(0, 0, Width, Height)); Canvas.Brush.Color := clBlue; for lCountY := 0 to 1 do begin for lCountX := 0 to 2 do begin lIndex := lCountX + lCountY * 3; if fStati[lIndex] then begin Canvas.FillRect(Rect(lCountX * lPartWidth, lCountY * lPartHeight, (lCountX + 1) * lPartWidth, (lCountY + 1) * lPartHeight)); end else begin end; end; end; Canvas.Pen.Color := clBlack; Canvas.MoveTo(0, Height div 2); Canvas.LineTo(Width, Height div 2); Canvas.MoveTo(lPartWidth, 0); Canvas.LineTo(lPartWidth, Height); Canvas.MoveTo(lPartWidth * 2, 0); Canvas.LineTo(lPartWidth * 2, Height); end; end. |
Re: Multiselect mit Strg + Maus (wie?)
Hallo,
Danke für die Antworten. @ibp Wenn ich die Flagrückstellung weglasse, erfolgt eine Übernahme der Werte nur bei jeden zweiten Klick und bei den nächsten Klick wird der Wert auch übernommen, obwohl dieser die Auswahl löschen und sich normal verhalten sollte. Mal schauen woran das liegt. @SirThornberry Deine Lösung ist OK. Hat für mich nur den Nachteil, das mit einem festen Statuspuffer gearbeitet wird, aber das läst sich ja ändern. Ich werde sehen was ich davon umsetze. Gruß |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:39 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