gpt4 book ai didi

delphi - 将 TSwitch 添加到每个 TListView 项目

转载 作者:行者123 更新时间:2023-12-01 16:45:35 25 4
gpt4 key购买 nike

我没有尝试过这个,因为我不知道从哪里开始。

是否可以将 FMX TSwitch 添加到 FMX TListViewitem 中?

任何帮助/建议将不胜感激。

谢谢

最佳答案

您首先必须记住 TListView 控件的整个设计。当它包含大量元素时,它的重量非常轻。您可能有一百万个项目,您肯定不希望实例化一百万个开关控件。因此,您并不需要将控件作为容器嵌入到每个项目中,例如 TListBox 允许的那样。

话虽如此,假设您对每个单独的列表项执行最少的绘制,以与 TListView 的设计保持一致。这需要创建从 TListItemObject 继承的虚拟对象以与每个项目关联。这些对象允许任何项目的现有内置元素,例如配件或位图。

这是我为帮助您入门而整理的非常粗略演示,您需要根据需要更改绘图的外观。

启动一个新的 FMX 应用程序,放置一个 TListView,然后使用此单元代替主窗体的单元:

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.

Screenshot

注意:这是用 Delphi 10 Seattle 编写的。

我认为您唯一的其他选择是:

  1. 为每个项目实例化一个 TSwitch 并使用与上面相同的方法渲染它(非常草率,我不推荐)
  2. 弄清楚如何使用样式实现标准 TSwitch 的绘制,再次使用与上面相同的方法(这可能是性能和视觉适应的最佳选择)
  3. 改用 TListBox,具体取决于您打算如何使用列表(这对于大量项目来说会非常繁重)

我在 a separate question / answer 中更深入地了解了 Firemonkey 中 TListViewTListBox 之间的差异。 .

关于delphi - 将 TSwitch 添加到每个 TListView 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37076388/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com