Je n'ai pas essayé cela parce que je ne saurais par où commencer.Ajouter TSwitch à chaque élément TListView
Est-il possible d'ajouter un commutateur FMX dans un TListViewitem FMX?
Toute aide ou suggestion serait grandement appréciée.
Merci,
Je n'ai pas essayé cela parce que je ne saurais par où commencer.Ajouter TSwitch à chaque élément TListView
Est-il possible d'ajouter un commutateur FMX dans un TListViewitem FMX?
Toute aide ou suggestion serait grandement appréciée.
Merci,
Vous devez d'abord garder à l'esprit la conception de l'ensemble du contrôle TListView
. Il est conçu pour être très léger lorsqu'il contient un grand nombre d'éléments. Vous pouvez avoir un million d'éléments, vous ne voulez certainement pas un million de contrôles de commutateur instanciés. Par conséquent, il n'est pas fait pour vous d'intégrer des contrôles dans chaque élément en tant que conteneur, comme le permet le TListBox
. Cela étant dit, il est supposé que vous effectuez un dessin minimal sur chaque élément de liste pour être cohérent avec la conception du TListView
. Cela nécessite de créer des objets virtuels hérités de TListItemObject
pour être associés à chaque élément. Ces objets autorisent les éléments intégrés existants de tout élément, tel que l'accessoire ou le bitmap.
Voici un démodé démo J'ai jeté ensemble pour vous aider à démarrer, vous auriez besoin de changer le dessin dont vous avez besoin pour regarder.
Démarrer une nouvelle application FMX, laissez tomber un TListView
, et utiliser cet appareil en place de l'unité de votre principale forme:
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.
NOTE: Ceci a été écrit en Delphi 10 Seattle.
Vos seules autres options que je crois, sont soit:
TSwitch
pour chaque élément et de le rendre en utilisant la même méthode que ci-dessus (très bâclée, je ne recommande pas)TSwitch
en utilisant des styles, toujours en utilisant la même méthode que ci-dessus (qui est probablement la meilleure option pour la performance et l'adaptation visuelle)je suis allé un peu plus en profondeur sur les différences entre un TListView
et un TListBox
dans FireMonkey en a separate question/answer.
Sur le plan positif, c'est beaucoup plus efficace que le dessin standard, sans animations, et fiable au clic (parce que le 'TSwitch' a quelques problèmes étranges). Cependant, il y a un autre problème où simplement sélectionner une ligne va basculer l'interrupteur. –
Merci beaucoup @Jerry, exactement ce que je cherche. –
@ 6String_Coder Voici une bonne implémentation sans la complexité que j'ai déjà ajoutée: http://stackoverflow.com/questions/37083809/click-events-being-caught-by-list-view-parent-item Long histoire courte, je crée un composant de contrôleur de vue liste qui vous permet de "concevoir" les éléments de vue de la liste dans un éditeur de composant au moment du design. –
J'ai essayé de le faire, et je ne vois pas de moyen facile de le faire au moment du design. Peut-être qu'il existe une option d'exécution. –