Ich habe dies nicht versucht, weil ich nicht wissen würde, wo ich anfangen soll.Hinzufügen TSwitch zu jedem TListView Element
Kann ich einen FMX TSwitch in ein FMX TListViewitem einfügen?
Jede Hilfe/Vorschläge würde sehr geschätzt werden.
Danke,
Ich habe dies nicht versucht, weil ich nicht wissen würde, wo ich anfangen soll.Hinzufügen TSwitch zu jedem TListView Element
Kann ich einen FMX TSwitch in ein FMX TListViewitem einfügen?
Jede Hilfe/Vorschläge würde sehr geschätzt werden.
Danke,
Sie zuerst das gesamte Design der TListView
Kontrolle im Auge behalten müssen. Es soll sehr leicht sein, wenn es eine große Anzahl von Gegenständen enthält. Sie können eine Million Elemente haben, Sie wollen sicherlich nicht eine Million Switch-Steuerelemente instanziiert. Daher ist es nicht für Sie vorgesehen, Steuerelemente in jedes Element als einen Container einzubetten, wie es beispielsweise der TListBox
ermöglicht.
Es wird davon ausgegangen, dass Sie minimale Zeichnung auf jedem einzelnen Listenelement durchführen, um mit dem Design der TListView
konsistent zu sein. Dazu müssen virtuelle Objekte erstellt werden, die von TListItemObject
geerbt wurden, um mit jedem Element verknüpft zu werden. Diese Objekte ermöglichen die vorhandenen integrierten Elemente eines beliebigen Elements, z. B. des Zubehörs oder der Bitmap.
Hier ist eine sehr grobe Demo Ich warf zusammen, um Sie zu beginnen, müssten Sie die Zeichnung ändern, wie Sie es brauchen, um zu sehen.
eine neue FMX-Anwendung starten, ein TListView
fallen, und verwenden Sie dieses Gerät anstelle Ihrer Hauptgerätes Form:
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base,
FMX.ListView, FMX.Controls.Presentation, FMX.StdCtrls;
type
TListItemSwitch = class(TListItemSimpleControl)
private
FIsChecked: Boolean;
FOnSwitch: TNotifyEvent;
procedure SetIsChecked(const AValue: Boolean);
protected
function MouseDown(const Button: TMouseButton; const Shift: TShiftState; const MousePos: TPointF): Boolean;
override;
procedure DoSwitch; virtual;
public
constructor Create(const AOwner: TListItem); override;
destructor Destroy; override;
procedure Render(const Canvas: TCanvas; const DrawItemIndex: Integer; const DrawStates: TListItemDrawStates;
const SubPassNo: Integer = 0); override;
public
property IsChecked: Boolean read FIsChecked write SetIsChecked;
property OnSwitch: TNotifyEvent read FOnSwitch write FOnSwitch;
end;
TForm1 = class(TForm)
ListView1: TListView;
procedure ListView1UpdateObjects(const Sender: TObject;
const AItem: TListViewItem);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
{ TListItemSwitch }
constructor TListItemSwitch.Create(const AOwner: TListItem);
begin
inherited;
end;
destructor TListItemSwitch.Destroy;
begin
inherited;
end;
procedure TListItemSwitch.DoSwitch;
begin
FIsChecked:= not FIsChecked;
if Assigned(OnSwitch) then
OnSwitch(Self);
end;
function TListItemSwitch.MouseDown(const Button: TMouseButton;
const Shift: TShiftState; const MousePos: TPointF): Boolean;
begin
if (Button = TMouseButton.mbLeft) and Enabled then begin
DoSwitch;
end;
inherited;
end;
procedure TListItemSwitch.Render(const Canvas: TCanvas;
const DrawItemIndex: Integer; const DrawStates: TListItemDrawStates;
const SubPassNo: Integer);
var
R, R2: TRectF;
begin
inherited;
R:= Self.LocalRect;
R2:= R;
Canvas.BeginScene;
try
Canvas.Stroke.Kind:= TBrushKind.None;
Canvas.Fill.Kind:= TBrushKind.Solid;
Canvas.Fill.Color:= TAlphaColorRec.Skyblue;
Canvas.FillRect(R, 8, 8,
[TCorner.TopLeft, TCorner.TopRight, TCorner.BottomLeft, TCorner.BottomRight],
1.0, TCornerType.Round);
if IsChecked then begin
R2.Left:= R.Right - 20;
R2.Width:= 20;
end else begin
R2.Left:= R.Left;
R2.Width:= 20;
end;
Canvas.Fill.Color:= TAlphaColorRec.Black;
Canvas.FillRect(R2, 8, 8,
[TCorner.TopLeft, TCorner.TopRight, TCorner.BottomLeft, TCorner.BottomRight],
1.0, TCornerType.Round);
finally
Canvas.EndScene;
end;
end;
procedure TListItemSwitch.SetIsChecked(const AValue: Boolean);
begin
FIsChecked:= AValue;
end;
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
I: TListViewItem;
begin
I:= ListView1.Items.Add;
I:= ListView1.Items.Add;
I:= ListView1.Items.Add;
I:= ListView1.Items.Add;
I:= ListView1.Items.Add;
I:= ListView1.Items.Add;
I:= ListView1.Items.Add;
I:= ListView1.Items.Add;
I:= ListView1.Items.Add;
end;
procedure TForm1.ListView1UpdateObjects(const Sender: TObject;
const AItem: TListViewItem);
var
S: TListItemSwitch;
begin
S:= AItem.Objects.FindObject('Switch') as TListItemSwitch;
if S = nil then begin
S:= TListItemSwitch.Create(AItem);
S.Name:= 'Switch';
S.Align:= TListItemAlign.Trailing;
S.VertAlign:= TListItemAlign.Center;
S.Width:= 50;
S.Height:= 20;
S.IsChecked:= False;
end;
end;
end.
Hinweis: Dies wurde in Delphi 10 Seattle geschrieben.
Ihre einzige andere Optionen Ich glaube, sind entweder:
TSwitch
für jedes Element instanziiert und machen es nach dem gleichen Verfahren wie oben (sehr schlampig, ich nicht empfehlen)TSwitch
mit Stilen zu implementieren, wieder mit der gleichen Methode wie oben (das ist wahrscheinlich die beste Option für Leistung und visuelle Anpassung)TListBox
, je nachdem, wie Sie die Liste verwenden wollen (was auf einer großen Anzahl sehr schwer wäre ber der Elemente)ging ich ein wenig mehr in die Tiefe über die Unterschiede zwischen einem TListView
und einem TListBox
in Firemonkey in a separate question/answer.
Auf der positiven Seite, das ist viel effizienter als die Standard-One-less-Zeichnung, keine Animationen und zuverlässig auf den Klick (weil der "TSwitch" einige seltsame Störungen hat). Es gibt jedoch einen weiteren Fehler, bei dem durch einfaches Auswählen einer Leitung der Schalter umgeschaltet wird. –
Vielen Dank @Jerry, genau das, was ich suche. –
@ 6String_Coder Hier ist eine gute Implementierung davon ohne die Komplexität, die ich bereits oben hinzugefügt habe: http://stackoverflow.com/questions/37083809/click-events-being-caught-by-list-view-parent-item Long Kurz gesagt, ich erstelle eine Listenansicht-Controller-Komponente, mit der Sie die Elemente der Listenansicht in einem Design-Time-Komponenteneditor "entwerfen" können. –
Ich habe versucht, dies zu tun, und sehe keine einfache Möglichkeit, es zur Entwurfszeit zu tun. Vielleicht gibt es eine Laufzeitoption. –