Child controls of TCustomControl flicker when TGridPanel is in between - delphi

I have following DFM structure:
inherited FormSwitches: TFormSwitches
DoubleBuffered = True
object PnlMain: TPanel [0]
object pnlControl: TPanel
DoubleBuffered = True
ParentDoubleBuffered = False
object GridPanel1: TGridPanel
ParentFont = False
object pnlWP21: TPanel
object btnInfoWP21: TSpeedButton
end
object lblWP21: TLabel
end
object btnWP21: TcxButton
end
end
object pnlBuffWP21: TPanel
object lblBuffWP21: TLabel
end
object btnBuffWP21: TcxButton
end
end
end
end
end
end
Each row of GridPanel is identical to the others, so I provide here only one of them.
Here is the more detailed variant of it:
inherited FormSwitches: TFormSwitches
DoubleBuffered = True
object PnlMain: TPanel [0]
Align = alClient
object pnlControl: TPanel
BevelOuter = bvNone
BorderWidth = 10
BorderStyle = bsSingle
DoubleBuffered = True
ParentDoubleBuffered = False
object GridPanel1: TGridPanel
Align = alClient
ColumnCollection = <
item
Value = 50.000000000000000000
end
item
Value = 50.000000000000000000
end>
ControlCollection = <
item
Column = 0
Control = pnlWP21
Row = 1
end
item
Column = 1
Control = pnlBuffWP31
Row = 3
end
item
Column = 0
Control = pnlWP22
Row = 2
end
item
Column = 1
Control = pnlBuffWP22
Row = 2
end
item
Column = 0
Control = pnlWP31
Row = 3
end
item
Column = 0
Control = pnlWP32
Row = 4
end
item
Column = 1
Control = pnlBuffWP32
Row = 4
end
item
Column = 0
Control = Panel9
Row = 0
end
item
Column = 1
Control = Panel10
Row = 0
end
item
Column = 1
Control = pnlBuffWP21
Row = 1
end>
ParentFont = False
RowCollection = <
item
Value = 20.598092313651590000
end
item
Value = 19.243163829564510000
end
item
Value = 19.512568123178410000
end
item
Value = 20.774380861810620000
end
item
Value = 19.871794871794870000
end>
object pnlWP21: TPanel
Align = alClient
Padding.Left = 3
Padding.Top = 3
Padding.Right = 3
Padding.Bottom = 3
object btnInfoWP21: TSpeedButton
AlignWithMargins = True
Margins.Left = 0
Margins.Top = 0
Margins.Bottom = 0
Align = alLeft
end
object lblWP21: TLabel
Width = 50
Align = alRight
Alignment = taCenter
AutoSize = False
Caption = '0'
Transparent = True
Layout = tlCenter
end
object btnWP21: TcxButton
Align = alClient
Caption = 'Workplace 2-1'
SpeedButtonOptions.GroupIndex = 1
end
end
object pnlBuffWP21: TPanel
Align = alClient
Padding.Left = 3
Padding.Top = 3
Padding.Right = 3
Padding.Bottom = 3
object lblBuffWP21: TLabel
Width = 50
Align = alRight
Alignment = taCenter
AutoSize = False
Caption = '0'
Transparent = True
Layout = tlCenter
end
object btnBuffWP21: TcxButton
Align = alClient
Caption = 'WP 2-1 BUFF'
SpeedButtonOptions.GroupIndex = 1
end
end
end
end
end
end
In this form I create an instance of TCustomControl:
TFormSwitches = class(TStdFrmNoneDB)
private
FLayout: TWPDrawing;
public
constructor Create(AOwner: TComponent); override;
end;
constructor TPrjFormPTLBufferingSwitch.Create(AOwner: TComponent);
begin
inherited;
FLayout := TWPDrawing.Create(Self);
FLayout.Parent := Self;
FLayout.Align := alClient;
FLayout.OnResize := WPLayoutResizeHandler;
pnlControl.Parent := FLayout;
end;
Its class sets the csAcceptsControls flag so that child controls of FLayout aren't flickering as the drawing is repainted.
TWPDrawing = class(TCustomControl)
public
constructor Create(AOwner: TComponent); override;
end;
constructor TWPDrawing.Create(AOwner: TComponent);
begin
inherited;
DoubleBuffered := True;
ControlStyle := ControlStyle + [csAcceptsControls];
end;
and they aren't flickering if they are simple TButtons having FLayout as their direct parent.
Everything changes when I drop the controls onto TGridPanel. They start flickering intensively (although not so wild as without the csAcceptsControls flag).
Each has DoubleBuffered = True. What else could be done to prevent flickering?

Related

TTreeViewItem in-place editor using styles

Using Delphi 10.4.2, I am adding an in-place editor for the text property of a custom TreeViewItem of a TTreeView in FMX, similar to the way the VCL version works. After failing to accomplish this in simple code, I decided to try my hand at accomplishing it using FMX Styles. Below is the code for my test project, along with the text of the StyleBook.
This is my first attempt at working with styles and it appears to work the way I expected it to in Windows. But I was wondering if this is the correct way to use styles, or am I missing something and/or using the styles feature wrong in some way?
Added...Or maybe a better question would be Is this the best way to access the "editor" object I added to the default TTreeViewItem style?
Note: For the style, I used the "Edit Custom Style" option for a TTreeViewItems, and simply added a TEdit to it and made it invisible by default. When you double click a node, the logic makes the TEdit visible and sets it text property to that of the Node. When you change the TEdit text and press Return, the TEdit is set to invisible again and the TEdit text is copied to the node text property. I plan on using this same component for Android and Apple versions of my program, but have not tested or worked on that yet. My assumption is that I will need to add the platforms to the StyleBook for the TreeViewItem, but the basic logic should work the same as Windows.
unit Unit1;
interface
uses System.SysUtils, System.Classes, System.UITypes, FMX.Forms, FMX.TreeView, FMX.Controls, FMX.Edit, FMX.Types,
FMX.Layouts;
type
TForm1 = class(TForm)
TreeView1: TTreeView;
StyleBook1: TStyleBook;
procedure FormShow(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
type
TVLinkTreeViewItem = class(TTreeViewItem)
private
fData: string;
procedure TreeViewItem1DblClick(Sender: TObject);
procedure EditorExit(Sender: TObject);
procedure EditorKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
procedure ApplyStyle; override;
public
property Data: string read fData write fData;
constructor Create(AOwner: TComponent); override;
end;
procedure TForm1.FormShow(Sender: TObject);
var
I, c: Integer;
vNode1,
vNode2: TVLinkTreeViewItem;
begin
TreeView1.BeginUpdate;
TreeView1.Clear;
for I := 0 to 4 do
begin
vNode1 := TVLinkTreeViewItem.Create(TreeView1);
vNode1.Text := 'Level 1 - '+ IntToStr(I);
vNode1.Data := vNode1.Name;
TreeView1.AddObject(vNode1);
for c := 0 to 4 do
begin
vNode2 := TVLinkTreeViewItem.Create(vNode1);
vNode2.Text := 'Level 2 - '+ IntToStr(c);
vNode2.Data := vNode2.Name;
vNode1.AddObject(vNode2);
end;
end;
TreeView1.ExpandAll;
treeView1.EndUpdate;
end;
{ TVLinkTreeViewItem }
constructor TVLinkTreeViewItem.Create(AOwner: TComponent);
begin
inherited;
self.StyleLookup := 'VLinkTreeViewItemStyle';
self.ApplyStyleLookup;
fData := '';
end;
procedure TVLinkTreeViewItem.ApplyStyle;
var
vEditor: TEdit;
begin
inherited;
//need to get Editor each time needed. Not sure why,
//but doesn't work when trying to set a component variable called fEditor here,
//then have the OnXXXX routines use fEditor, instead of finding the editor themselves
vEditor:= FindStyleResource('Editor') as TEdit;
if Assigned(vEditor) then
begin
vEditor.OnKeyDown := EditorKeyUp;
OnDblClick := TreeViewItem1DblClick;
vEditor.OnExit := EditorExit;
end;
end;
procedure TVLinkTreeViewItem.TreeViewItem1DblClick(Sender: TObject);
var
vEditor: TEdit;
begin
//need to get Editor each time needed. Not sure why,
//but doesn't work when trying to set a component variable called fEditor in ApplyStyle.
vEditor:= FindStyleResource('Editor') as TEdit;
if assigned(vEditor) then
begin
vEditor.Visible := true;
vEditor.Text := Text;
vEditor.SetFocus;
vEditor.SelectAll;
end;
end;
procedure TVLinkTreeViewItem.EditorKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
var
vEditor: TEdit;
begin
inherited;
//need to get Editor each time needed. Not sure why,
//but doesn't work when trying to set a component variable called fEditor in ApplyStyle.
vEditor:= FindStyleResource('Editor') as TEdit;
if not assigned(vEditor) then
exit;
if Key = vkReturn then
begin
Text := vEditor.Text;
vEditor.Visible := false;
end
else if Key in [vkEscape, vkCancel, vkTab, vkHardwareBack] then
begin
vEditor.Visible := false;
end;
end;
procedure TVLinkTreeViewItem.EditorExit(Sender: TObject);
var
vEditor: TEdit;
begin
//need to get Editor each time needed. Not sure why,
//but doesn't work when trying to set a component variable called fEditor in ApplyStyle.
vEditor:= FindStyleResource('Editor') as TEdit;
if Assigned(vEditor) then
vEditor.Visible := false;
end;
end.
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 500
ClientWidth = 640
StyleBook = StyleBook1
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnShow = FormShow
DesignerMasterStyle = 0
object TreeView1: TTreeView
Align = Left
Size.Width = 269.000000000000000000
Size.Height = 500.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
Viewport.Width = 265.000000000000000000
Viewport.Height = 496.000000000000000000
end
object StyleBook1: TStyleBook
Styles = <
item
end
item
Platform = 'Windows 10 Desktop'
ResourcesBin = {
464D585F5354594C4520322E35010616564C696E6B5472656556696577497465
6D5374796C650395050631564C696E6B54726565566965774974656D5374796C
657472656576696577657870616E646572627574746F6E7374796C6503E10306
23564C696E6B54726565566965774974656D5374796C65436865636B426F7853
74796C6503E40B005450463007544C61796F757400095374796C654E616D6506
16564C696E6B54726565566965774974656D5374796C6505416C69676E070643
656E7465720A53697A652E576964746805000000000000808407400B53697A65
2E4865696768740500000000000000A003401453697A652E506C6174666F726D
44656661756C7408085461624F726465720236000C545370656564427574746F
6E00095374796C654E616D650606627574746F6E05416C69676E07044C656674
0C4D617267696E732E4C6566740500000000000000C000400B4D617267696E73
2E546F700500000000000000C000400D4D617267696E732E5269676874050000
0000000000C000400E4D617267696E732E426F74746F6D0500000000000000C0
00400A506F736974696F6E2E580500000000000000C000400A506F736974696F
6E2E590500000000000000C000400A53697A652E576964746805000000000000
00F002400B53697A652E4865696768740500000000000000E002401453697A65
2E506C6174666F726D44656661756C74080B5374796C654C6F6F6B7570063156
4C696E6B54726565566965774974656D5374796C657472656576696577657870
616E646572627574746F6E7374796C65000007544C61796F75740005416C6967
6E0708436F6E74656E74730C4D617267696E732E4C6566740500000000000000
A003400A53697A652E57696474680500000000000000F506400B53697A652E48
65696768740500000000000000A003401453697A652E506C6174666F726D4465
6661756C7408000954436865636B426F7800095374796C654E616D6506056368
65636B05416C69676E07044C6566740843616E466F637573081244697361626C
65466F637573456666656374090A53697A652E57696474680500000000000000
A003400B53697A652E4865696768740500000000000000A003401453697A652E
506C6174666F726D44656661756C74080B5374796C654C6F6F6B75700623564C
696E6B54726565566965774974656D5374796C65436865636B426F785374796C
6500000654476C79706800095374796C654E616D65060A676C7970687374796C
650C4D617267696E732E4C65667405000000000000008000400B4D617267696E
732E546F70050000000000000080FF3F0D4D617267696E732E52696768740500
0000000000008000400E4D617267696E732E426F74746F6D0500000000000000
80FF3F05416C69676E07044C6566740A53697A652E5769647468050000000000
00008003400B53697A652E48656967687405000000000000008003401453697A
652E506C6174666F726D44656661756C7408000016544163746976655374796C
65546578744F626A65637400095374796C654E616D6506047465787405416C69
676E0706436C69656E74064C6F636B6564090A53697A652E5769647468050000
0000000000E106400B53697A652E4865696768740500000000000000A0034014
53697A652E506C6174666F726D44656661756C74080454657874060454657874
155465787453657474696E67732E576F72645772617008165465787453657474
696E67732E486F727A416C69676E07074C656164696E670D536861646F775669
7369626C65080D41637469766554726967676572070853656C65637465640B41
6374697665436F6C6F720708636C61426C61636B000005544564697400095374
796C654E616D650606456469746F7219546F7563682E496E7465726163746976
6547657374757265730B074C6F6E6754617009446F75626C655461700005416C
69676E0706436C69656E740B5374796C654C6F6F6B7570060965646974737479
6C65085461624F7264657202000A53697A652E57696474680500000000000000
E106400B53697A652E4865696768740500000000000000A003401453697A652E
506C6174666F726D44656661756C74080756697369626C650800000000545046
3007544C61796F757400095374796C654E616D650631564C696E6B5472656556
6965774974656D5374796C657472656576696577657870616E64657262757474
6F6E7374796C6505416C69676E070643656E7465720B4D617267696E732E546F
70050000000000000080FF3F0A53697A652E5769647468050000000000008084
07400B53697A652E4865696768740500000000000000A003401453697A652E50
6C6174666F726D44656661756C74080756697369626C6508085461624F726465
720237000554506174680005416C69676E070643656E74657209446174612E50
6174680A400000000500000000000000D36D3F431BEF4843010000001749E043
BA09E54301000000D36D3F43C73B344401000000D36D3F431BEF484303000000
D36D3F431BEF48430A46696C6C2E436F6C6F720708636C61426C61636B064C6F
636B6564090748697454657374080A53697A652E576964746805000000000000
00E001400B53697A652E4865696768740500000000000000E001401453697A65
2E506C6174666F726D44656661756C74080B5374726F6B652E4B696E6407044E
6F6E65000F54466C6F6174416E696D6174696F6E00084475726174696F6E0500
0000000017B7D1F13F0C50726F70657274794E616D6506074F7061636974790A
537461727456616C756505000000000000000000000953746F7056616C756505
0000000000000080FF3F075472696767657206104973457870616E6465643D66
616C73650E54726967676572496E7665727365060F4973457870616E6465643D
747275650000000554506174680005416C69676E070643656E74657209446174
612E506174680A400000000500000000000000CB11CF4379E93C4301000000CB
11CF4396230A44010000007DBF1E4296230A4401000000CB11CF4379E93C4303
000000CB11CF4379E93C430A46696C6C2E436F6C6F720708636C61426C61636B
064C6F636B656409074869745465737408074F70616369747905000000000000
000000000A53697A652E57696474680500000000000000E001400B53697A652E
4865696768740500000000000000E001401453697A652E506C6174666F726D44
656661756C74080B5374726F6B652E4B696E6407044E6F6E65000F54466C6F61
74416E696D6174696F6E00084475726174696F6E05000000000017B7D1F13F0C
50726F70657274794E616D6506074F7061636974790A537461727456616C7565
05000000000000000000000953746F7056616C7565050000000000000080FF3F
0754726967676572060F4973457870616E6465643D747275650E547269676765
72496E766572736506104973457870616E6465643D66616C7365000000005450
463007544C61796F757400095374796C654E616D650623564C696E6B54726565
566965774974656D5374796C65436865636B426F785374796C6505416C69676E
070643656E7465720A53697A652E576964746805000000000000808407400B53
697A652E4865696768740500000000000000A003401453697A652E506C617466
6F726D44656661756C74080756697369626C6508085461624F72646572021200
07544C61796F75740005416C69676E07044C6566740A53697A652E5769647468
05000000000000009003400B53697A652E4865696768740500000000000000A0
03401453697A652E506C6174666F726D44656661756C7408001154436865636B
5374796C654F626A65637400095374796C654E616D65060A6261636B67726F75
6E6405416C69676E070643656E746572074361704D6F6465070454696C65064C
6F636B6564090C536F757263654C6F6F6B7570061B57696E646F777320313020
4465736B746F707374796C652E706E670A53697A652E57696474680500000000
000000D002400B53697A652E4865696768740500000000000000D00240145369
7A652E506C6174666F726D44656661756C740808577261704D6F646507064365
6E7465720D416374697665547269676765720707436865636B65640A41637469
76654C696E6B0E010F536F75726365526563742E4C6566740500000000000000
F803400E536F75726365526563742E546F70050000000000000092064010536F
75726365526563742E52696768740500000000000000B0044011536F75726365
526563742E426F74746F6D05000000000000009F06400001055363616C650500
000000000000C0FF3F0F536F75726365526563742E4C65667405000000000000
00B804400E536F75726365526563742E546F700500000000000000DB06401053
6F75726365526563742E5269676874050000000000000082054011536F757263
65526563742E426F74746F6D0500000000000000EE06400001055363616C6505
000000000000008000400F536F75726365526563742E4C656674050000000000
0000F804400E536F75726365526563742E546F70050000000000000092074010
536F75726365526563742E52696768740500000000000000B0054011536F7572
6365526563742E426F74746F6D05000000000000009F074000000A536F757263
654C696E6B0E010F536F75726365526563742E4C6566740500000000000000C0
00400E536F75726365526563742E546F70050000000000000092064010536F75
726365526563742E5269676874050000000000000080034011536F7572636552
6563742E426F74746F6D05000000000000009F06400001055363616C65050000
0000000000C0FF3F0F536F75726365526563742E4C6566740500000000000000
8001400E536F75726365526563742E546F700500000000000000DB064010536F
75726365526563742E52696768740500000000000000B8034011536F75726365
526563742E426F74746F6D0500000000000000EE06400001055363616C650500
0000000000008000400F536F75726365526563742E4C65667405000000000000
00C001400E536F75726365526563742E546F7005000000000000009207401053
6F75726365526563742E5269676874050000000000000080044011536F757263
65526563742E426F74746F6D05000000000000009F0740000007486F744C696E
6B0E010F536F75726365526563742E4C65667405000000000000008803400E53
6F75726365526563742E546F70050000000000000092064010536F7572636552
6563742E52696768740500000000000000F0034011536F75726365526563742E
426F74746F6D05000000000000009F06400001055363616C6505000000000000
00C0FF3F0F536F75726365526563742E4C6566740500000000000000C803400E
536F75726365526563742E546F700500000000000000DB064010536F75726365
526563742E52696768740500000000000000B0044011536F7572636552656374
2E426F74746F6D0500000000000000EE06400001055363616C65050000000000
00008000400F536F75726365526563742E4C6566740500000000000000880440
0E536F75726365526563742E546F70050000000000000092074010536F757263
65526563742E52696768740500000000000000F0044011536F75726365526563
742E426F74746F6D05000000000000009F074000000D416374697665486F744C
696E6B0E010F536F75726365526563742E4C6566740500000000000000B40440
0E536F75726365526563742E546F70050000000000000092064010536F757263
65526563742E52696768740500000000000000E8044011536F75726365526563
742E426F74746F6D05000000000000009F06400001055363616C650500000000
000000C0FF3F0F536F75726365526563742E4C65667405000000000000008605
400E536F75726365526563742E546F700500000000000000DB064010536F7572
6365526563742E52696768740500000000000000AC054011536F757263655265
63742E426F74746F6D0500000000000000EE06400001055363616C6505000000
000000008000400F536F75726365526563742E4C6566740500000000000000B4
05400E536F75726365526563742E546F70050000000000000092074010536F75
726365526563742E52696768740500000000000000E8054011536F7572636552
6563742E426F74746F6D05000000000000009F074000000B466F63757365644C
696E6B0E010F536F75726365526563742E4C6566740500000000000000880340
0E536F75726365526563742E546F70050000000000000092064010536F757263
65526563742E52696768740500000000000000F0034011536F75726365526563
742E426F74746F6D05000000000000009F06400001055363616C650500000000
000000C0FF3F0F536F75726365526563742E4C6566740500000000000000C803
400E536F75726365526563742E546F700500000000000000DB064010536F7572
6365526563742E52696768740500000000000000B0044011536F757263655265
63742E426F74746F6D0500000000000000EE06400001055363616C6505000000
000000008000400F536F75726365526563742E4C656674050000000000000088
04400E536F75726365526563742E546F70050000000000000092074010536F75
726365526563742E52696768740500000000000000F0044011536F7572636552
6563742E426F74746F6D05000000000000009F0740000011416374697665466F
63757365644C696E6B0E010F536F75726365526563742E4C6566740500000000
000000B404400E536F75726365526563742E546F700500000000000000920640
10536F75726365526563742E52696768740500000000000000E8044011536F75
726365526563742E426F74746F6D05000000000000009F06400001055363616C
650500000000000000C0FF3F0F536F75726365526563742E4C65667405000000
000000008605400E536F75726365526563742E546F700500000000000000DB06
4010536F75726365526563742E52696768740500000000000000AC054011536F
75726365526563742E426F74746F6D0500000000000000EE0640000105536361
6C6505000000000000008000400F536F75726365526563742E4C656674050000
0000000000B405400E536F75726365526563742E546F70050000000000000092
074010536F75726365526563742E52696768740500000000000000E805401153
6F75726365526563742E426F74746F6D05000000000000009F07400000000000
1654427574746F6E5374796C65546578744F626A65637400095374796C654E61
6D6506047465787405416C69676E0706436C69656E74064C6F636B6564090C4D
617267696E732E4C6566740500000000000000C000400A53697A652E57696474
680500000000000000F406400B53697A652E4865696768740500000000000000
A003401453697A652E506C6174666F726D44656661756C74080D536861646F77
56697369626C650808486F74436F6C6F720708636C61426C61636B0C466F6375
736564436F6C6F720708636C61426C61636B0B4E6F726D616C436F6C6F720708
636C61426C61636B0C50726573736564436F6C6F720708636C61426C61636B00
0000}
end>
Left = 116
Top = 150
end
end
object TStyleContainer
object TLayout
StyleName = 'VLinkTreeViewItemStyle'
Align = Center
Size.Width = 265.000000000000000000
Size.Height = 20.000000000000000000
Size.PlatformDefault = False
Visible = False
TabOrder = 52
object TSpeedButton
StyleName = 'button'
Align = Left
Margins.Left = 3.000000000000000000
Margins.Top = 3.000000000000000000
Margins.Right = 3.000000000000000000
Margins.Bottom = 3.000000000000000000
Position.X = 3.000000000000000000
Position.Y = 3.000000000000000000
Size.Width = 15.000000000000000000
Size.Height = 14.000000000000000000
Size.PlatformDefault = False
StyleLookup = 'VLinkTreeViewItemStyletreeviewexpanderbuttonstyle'
end
object TLayout
Align = Contents
Margins.Left = 20.000000000000000000
Size.Width = 245.000000000000000000
Size.Height = 20.000000000000000000
Size.PlatformDefault = False
object TCheckBox
StyleName = 'check'
Align = Left
CanFocus = False
DisableFocusEffect = True
Size.Width = 20.000000000000000000
Size.Height = 20.000000000000000000
Size.PlatformDefault = False
StyleLookup = 'VLinkTreeViewItemStyleCheckBoxStyle'
end
object TGlyph
StyleName = 'glyphstyle'
Margins.Left = 2.000000000000000000
Margins.Top = 1.000000000000000000
Margins.Right = 2.000000000000000000
Margins.Bottom = 1.000000000000000000
Align = Left
Size.Width = 16.000000000000000000
Size.Height = 16.000000000000000000
Size.PlatformDefault = False
end
object TActiveStyleTextObject
StyleName = 'text'
Align = Client
Locked = True
Size.Width = 225.000000000000000000
Size.Height = 20.000000000000000000
Size.PlatformDefault = False
Text = 'Text'
TextSettings.WordWrap = False
TextSettings.HorzAlign = Leading
ShadowVisible = False
ActiveTrigger = Selected
ActiveColor = claBlack
end
object TEdit
StyleName = 'Editor'
Touch.InteractiveGestures = [LongTap, DoubleTap]
Align = Client
StyleLookup = 'editstyle'
TabOrder = 0
Size.Width = 225.000000000000000000
Size.Height = 20.000000000000000000
Size.PlatformDefault = False
Visible = False
end
end
end
object TLayout
StyleName = 'VLinkTreeViewItemStyletreeviewexpanderbuttonstyle'
Align = Center
Margins.Top = 1.000000000000000000
Size.Width = 265.000000000000000000
Size.Height = 20.000000000000000000
Size.PlatformDefault = False
Visible = False
TabOrder = 54
object TPath
Align = Center
Data.Path = {
0500000000000000D36D3F431BEF4843010000001749E043BA09E54301000000
D36D3F43C73B344401000000D36D3F431BEF484303000000D36D3F431BEF4843}
Fill.Color = claBlack
Locked = True
HitTest = False
Size.Width = 7.000000000000000000
Size.Height = 7.000000000000000000
Size.PlatformDefault = False
Stroke.Kind = None
object TFloatAnimation
Duration = 0.000099999997473788
PropertyName = 'Opacity'
StartValue = 0.000000000000000000
StopValue = 1.000000000000000000
Trigger = 'IsExpanded=false'
TriggerInverse = 'IsExpanded=true'
end
end
object TPath
Align = Center
Data.Path = {
0500000000000000CB11CF4379E93C4301000000CB11CF4396230A4401000000
7DBF1E4296230A4401000000CB11CF4379E93C4303000000CB11CF4379E93C43}
Fill.Color = claBlack
Locked = True
HitTest = False
Opacity = 0.000000000000000000
Size.Width = 7.000000000000000000
Size.Height = 7.000000000000000000
Size.PlatformDefault = False
Stroke.Kind = None
object TFloatAnimation
Duration = 0.000099999997473788
PropertyName = 'Opacity'
StartValue = 0.000000000000000000
StopValue = 1.000000000000000000
Trigger = 'IsExpanded=true'
TriggerInverse = 'IsExpanded=false'
end
end
end
object TLayout
StyleName = 'VLinkTreeViewItemStyleCheckBoxStyle'
Align = Center
Size.Width = 265.000000000000000000
Size.Height = 20.000000000000000000
Size.PlatformDefault = False
Visible = False
TabOrder = 18
object TLayout
Align = Left
Size.Width = 18.000000000000000000
Size.Height = 20.000000000000000000
Size.PlatformDefault = False
object TCheckStyleObject
StyleName = 'background'
Align = Center
CapMode = Tile
Locked = True
SourceLookup = 'Windows 10 Desktopstyle.png'
Size.Width = 13.000000000000000000
Size.Height = 13.000000000000000000
Size.PlatformDefault = False
WrapMode = Center
ActiveTrigger = Checked
ActiveLink = <
item
SourceRect.Left = 31.000000000000000000
SourceRect.Top = 146.000000000000000000
SourceRect.Right = 44.000000000000000000
SourceRect.Bottom = 159.000000000000000000
end
item
Scale = 1.500000000000000000
SourceRect.Left = 46.000000000000000000
SourceRect.Top = 219.000000000000000000
SourceRect.Right = 65.000000000000000000
SourceRect.Bottom = 238.000000000000000000
end
item
Scale = 2.000000000000000000
SourceRect.Left = 62.000000000000000000
SourceRect.Top = 292.000000000000000000
SourceRect.Right = 88.000000000000000000
SourceRect.Bottom = 318.000000000000000000
end>
SourceLink = <
item
SourceRect.Left = 3.000000000000000000
SourceRect.Top = 146.000000000000000000
SourceRect.Right = 16.000000000000000000
SourceRect.Bottom = 159.000000000000000000
end
item
Scale = 1.500000000000000000
SourceRect.Left = 4.000000000000000000
SourceRect.Top = 219.000000000000000000
SourceRect.Right = 23.000000000000000000
SourceRect.Bottom = 238.000000000000000000
end
item
Scale = 2.000000000000000000
SourceRect.Left = 6.000000000000000000
SourceRect.Top = 292.000000000000000000
SourceRect.Right = 32.000000000000000000
SourceRect.Bottom = 318.000000000000000000
end>
HotLink = <
item
SourceRect.Left = 17.000000000000000000
SourceRect.Top = 146.000000000000000000
SourceRect.Right = 30.000000000000000000
SourceRect.Bottom = 159.000000000000000000
end
item
Scale = 1.500000000000000000
SourceRect.Left = 25.000000000000000000
SourceRect.Top = 219.000000000000000000
SourceRect.Right = 44.000000000000000000
SourceRect.Bottom = 238.000000000000000000
end
item
Scale = 2.000000000000000000
SourceRect.Left = 34.000000000000000000
SourceRect.Top = 292.000000000000000000
SourceRect.Right = 60.000000000000000000
SourceRect.Bottom = 318.000000000000000000
end>
ActiveHotLink = <
item
SourceRect.Left = 45.000000000000000000
SourceRect.Top = 146.000000000000000000
SourceRect.Right = 58.000000000000000000
SourceRect.Bottom = 159.000000000000000000
end
item
Scale = 1.500000000000000000
SourceRect.Left = 67.000000000000000000
SourceRect.Top = 219.000000000000000000
SourceRect.Right = 86.000000000000000000
SourceRect.Bottom = 238.000000000000000000
end
item
Scale = 2.000000000000000000
SourceRect.Left = 90.000000000000000000
SourceRect.Top = 292.000000000000000000
SourceRect.Right = 116.000000000000000000
SourceRect.Bottom = 318.000000000000000000
end>
FocusedLink = <
item
SourceRect.Left = 17.000000000000000000
SourceRect.Top = 146.000000000000000000
SourceRect.Right = 30.000000000000000000
SourceRect.Bottom = 159.000000000000000000
end
item
Scale = 1.500000000000000000
SourceRect.Left = 25.000000000000000000
SourceRect.Top = 219.000000000000000000
SourceRect.Right = 44.000000000000000000
SourceRect.Bottom = 238.000000000000000000
end
item
Scale = 2.000000000000000000
SourceRect.Left = 34.000000000000000000
SourceRect.Top = 292.000000000000000000
SourceRect.Right = 60.000000000000000000
SourceRect.Bottom = 318.000000000000000000
end>
ActiveFocusedLink = <
item
SourceRect.Left = 45.000000000000000000
SourceRect.Top = 146.000000000000000000
SourceRect.Right = 58.000000000000000000
SourceRect.Bottom = 159.000000000000000000
end
item
Scale = 1.500000000000000000
SourceRect.Left = 67.000000000000000000
SourceRect.Top = 219.000000000000000000
SourceRect.Right = 86.000000000000000000
SourceRect.Bottom = 238.000000000000000000
end
item
Scale = 2.000000000000000000
SourceRect.Left = 90.000000000000000000
SourceRect.Top = 292.000000000000000000
SourceRect.Right = 116.000000000000000000
SourceRect.Bottom = 318.000000000000000000
end>
end
end
object TButtonStyleTextObject
StyleName = 'text'
Align = Client
Locked = True
Margins.Left = 3.000000000000000000
Size.Width = 244.000000000000000000
Size.Height = 20.000000000000000000
Size.PlatformDefault = False
ShadowVisible = False
HotColor = claBlack
FocusedColor = claBlack
NormalColor = claBlack
PressedColor = claBlack
end
end
end

How to refresh Livebinding for TListView and TFDMemTable?

I have a TListView livebinded with TFDMemTable. I also have a TButton that adds the item on the TFDMemTable which obviously shown in the TListView after adding the item. The TListView is located in one of the TTabItem of TTabControl.
My problem is, when I changed the tab at runtime and go back to TListView tab to add more item, the previously shown data will become empty after adding more item.
I can confirm that the data in the TFDMemTable are still intact including the newly added ones.
I suspect the livebinding needs to be refreshed in order to get all the data back to TListView.
Does anyone have any idea on how to refresh the livebinding at runtime?
P.S. I hope the above explains my issue clearly. Otherwise, please let me know if you need more details.
UPDATE 1: MINIMUM REPRODUCIBLE EXAMPLE
Here's the least that I can do for the MRE, not the exact scenario of my case but should be the same issue. You will come to notice after adding list on the TabItem2 and you go back to TabItem1 to add more item on the lists, the existing detail on the list will be gone.
FMX Procedure
unit TabbedFormwithNavigation;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.TabControl, FMX.StdCtrls, FMX.Controls.Presentation,
FMX.Gestures, System.Actions, FMX.ActnList, FMX.ListView.Types,
FMX.ListView.Appearances, FMX.ListView.Adapters.Base, REST.Types,
FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,
System.Rtti, System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.EngExt,
Fmx.Bind.DBEngExt, Data.Bind.Components, Data.Bind.DBScope, Data.DB,
FireDAC.Comp.DataSet, FireDAC.Comp.Client, REST.Response.Adapter, REST.Client,
Data.Bind.ObjectScope, FMX.ListView;
type
TTabbedwithNavigationForm = class(TForm)
TabControl1: TTabControl;
TabItem1: TTabItem;
TabItem2: TTabItem;
GestureManager1: TGestureManager;
ActionList1: TActionList;
NextTabAction1: TNextTabAction;
PreviousTabAction1: TPreviousTabAction;
lsv1: TListView;
rsc1: TRESTClient;
rsq1: TRESTRequest;
rsp1: TRESTResponse;
rsd1: TRESTResponseDataSetAdapter;
mtb1: TFDMemTable;
bdr1: TBindSourceDB;
bdl1: TBindingsList;
lsv2: TListView;
rsc2: TRESTClient;
rsq2: TRESTRequest;
rsp2: TRESTResponse;
rsd2: TRESTResponseDataSetAdapter;
mtb2: TFDMemTable;
bdr2: TBindSourceDB;
lcf1: TLinkListControlToField;
btn1: TButton;
lsv3: TListView;
mtb3: TFDMemTable;
strngfldmtb3brandname: TStringField;
strngfldmtb3brand: TStringField;
bdr3: TBindSourceDB;
lcf3: TLinkListControlToField;
lcf2: TLinkListControlToField;
pnl1: TPanel;
lbl1: TLabel;
pnl2: TPanel;
lbl2: TLabel;
pnl3: TPanel;
lbl3: TLabel;
procedure GestureDone(Sender: TObject; const EventInfo: TGestureEventInfo; var Handled: Boolean);
procedure FormCreate(Sender: TObject);
procedure FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
procedure lsv1ItemClick(const Sender: TObject; const AItem: TListViewItem);
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
TabbedwithNavigationForm: TTabbedwithNavigationForm;
implementation
{$R *.fmx}
procedure TTabbedwithNavigationForm.btn1Click(Sender: TObject);
var
brandname : string;
begin
brandname := mtb2.Lookup('name', lsv2.Items[lsv2.ItemIndex].Text, 'name');
// ShowMessage(lsv2.Items[lsv2.ItemIndex].Text);
if mtb3.Locate('brandname', brandname, []) = False then
begin
mtb3.DisableControls;
mtb3.Append;
mtb3.FieldByName('brandname').AsString := brandname;
mtb3.EnableControls;
mtb3.Post;
end;
end;
procedure TTabbedwithNavigationForm.FormCreate(Sender: TObject);
begin
{ This defines the default active tab at runtime }
TabControl1.ActiveTab := TabItem1;
rsq1.Execute;
end;
procedure TTabbedwithNavigationForm.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
begin
if Key = vkHardwareBack then
begin
if (TabControl1.ActiveTab = TabItem1) then
begin
Key := 0;
end;
end;
end;
procedure TTabbedwithNavigationForm.GestureDone(Sender: TObject; const EventInfo: TGestureEventInfo; var Handled: Boolean);
begin
case EventInfo.GestureID of
sgiLeft:
begin
if TabControl1.ActiveTab <> TabControl1.Tabs[TabControl1.TabCount - 1] then
TabControl1.ActiveTab := TabControl1.Tabs[TabControl1.TabIndex + 1];
Handled := True;
end;
sgiRight:
begin
if TabControl1.ActiveTab <> TabControl1.Tabs[0] then
TabControl1.ActiveTab := TabControl1.Tabs[TabControl1.TabIndex - 1];
Handled := True;
end;
end;
end;
procedure TTabbedwithNavigationForm.lsv1ItemClick(const Sender: TObject;
const AItem: TListViewItem);
var
SearchItem : String;
begin
//place the equivalent api for the meta click
SearchItem := lsv1.Items[lsv1.ItemIndex].Text;
rsc2.BaseURL := 'https://nm5c906csg.execute-api.ap-southeast-1.amazonaws.com/v0/dbqueries?search-item=' + SearchItem;
//execute api request for the searches
rsq2.Execute;
TabControl1.TabIndex := 1;
end;
end.
FMX File
object TabbedwithNavigationForm: TTabbedwithNavigationForm
Left = 0
Top = 0
Caption = 'Form56'
ClientHeight = 596
ClientWidth = 405
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnCreate = FormCreate
OnKeyUp = FormKeyUp
DesignerMasterStyle = 0
object TabControl1: TTabControl
Touch.GestureManager = GestureManager1
OnGesture = GestureDone
Align = Client
FullSize = True
Size.Width = 405.000000000000000000
Size.Height = 596.000000000000000000
Size.PlatformDefault = False
TabHeight = 49.000000000000000000
TabIndex = 1
TabOrder = 0
TabPosition = PlatformDefault
Sizes = (
405s
547s
405s
547s)
object TabItem1: TTabItem
CustomIcon = <
item
end>
IsSelected = False
Size.Width = 201.000000000000000000
Size.Height = 49.000000000000000000
Size.PlatformDefault = False
StyleLookup = 'tabitemfavorites'
TabOrder = 0
Text = 'TabItem1'
ExplicitSize.cx = 101.000000000000000000
ExplicitSize.cy = 49.000000000000000000
object lsv1: TListView
ItemAppearanceClassName = 'TListItemAppearance'
ItemEditAppearanceClassName = 'TListItemShowCheckAppearance'
HeaderAppearanceClassName = 'TListHeaderObjects'
FooterAppearanceClassName = 'TListHeaderObjects'
ItemIndex = 0
Align = Client
Size.Width = 405.000000000000000000
Size.Height = 487.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
OnItemClick = lsv1ItemClick
end
object pnl1: TPanel
Align = Top
Size.Width = 405.000000000000000000
Size.Height = 60.000000000000000000
Size.PlatformDefault = False
TabOrder = 1
object lbl1: TLabel
Align = Client
StyledSettings = [Family, FontColor]
Margins.Left = 60.000000000000000000
Margins.Right = 60.000000000000000000
Size.Width = 285.000000000000000000
Size.Height = 60.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 14.000000000000000000
TextSettings.Font.StyleExt = {00070000000000000004000000}
TextSettings.HorzAlign = Center
Text = 'Please select an item here to filter out items for TabItem2.'
TabOrder = 0
end
end
end
object TabItem2: TTabItem
CustomIcon = <
item
end>
IsSelected = True
Size.Width = 202.000000000000000000
Size.Height = 49.000000000000000000
Size.PlatformDefault = False
StyleLookup = 'tabitemcontacts'
TabOrder = 0
Text = 'TabItem2'
ExplicitSize.cx = 102.000000000000000000
ExplicitSize.cy = 49.000000000000000000
object lsv2: TListView
ItemAppearanceClassName = 'TImageListItemBottomDetailAppearance'
ItemEditAppearanceClassName = 'TImageListItemBottomDetailShowCheckAppearance'
HeaderAppearanceClassName = 'TListHeaderObjects'
FooterAppearanceClassName = 'TListHeaderObjects'
ItemIndex = 0
Align = Top
Position.Y = 60.000000000000000000
Size.Width = 405.000000000000000000
Size.Height = 221.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
end
object btn1: TButton
Align = Top
StyledSettings = [Family, FontColor]
Position.Y = 281.000000000000000000
Size.Width = 405.000000000000000000
Size.Height = 40.000000000000000000
Size.PlatformDefault = False
TabOrder = 1
Text = 'SELECT'
TextSettings.Font.Size = 14.000000000000000000
TextSettings.Font.StyleExt = {00070000000000000004000000}
OnClick = btn1Click
end
object lsv3: TListView
ItemAppearanceClassName = 'TImageListItemBottomDetailAppearance'
ItemEditAppearanceClassName = 'TImageListItemBottomDetailShowCheckAppearance'
HeaderAppearanceClassName = 'TListHeaderObjects'
FooterAppearanceClassName = 'TListHeaderObjects'
Align = Client
Size.Width = 405.000000000000000000
Size.Height = 166.000000000000000000
Size.PlatformDefault = False
TabOrder = 2
end
object pnl2: TPanel
Align = Top
Size.Width = 405.000000000000000000
Size.Height = 60.000000000000000000
Size.PlatformDefault = False
TabOrder = 3
object lbl2: TLabel
Align = Client
StyledSettings = [Family, FontColor]
Margins.Left = 30.000000000000000000
Margins.Right = 30.000000000000000000
Size.Width = 345.000000000000000000
Size.Height = 60.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 14.000000000000000000
TextSettings.Font.StyleExt = {00070000000000000004000000}
TextSettings.HorzAlign = Center
Text =
'Select an item below then click the "SELECT" button to list down' +
' the items selected.'
TabOrder = 0
end
end
object pnl3: TPanel
Align = Bottom
Position.Y = 487.000000000000000000
Size.Width = 405.000000000000000000
Size.Height = 60.000000000000000000
Size.PlatformDefault = False
TabOrder = 4
object lbl3: TLabel
Align = Client
StyledSettings = [Family]
Size.Width = 405.000000000000000000
Size.Height = 60.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.StyleExt = {00070000000000000004000000}
TextSettings.FontColor = claRed
TextSettings.HorzAlign = Center
Text =
'The error comes when you go back to TabItem1 and select another ' +
'item, the existing details on the list will be gone.'
TabOrder = 0
end
end
end
end
object GestureManager1: TGestureManager
Sensitivity = 80.000000000000000000
Left = 48
Top = 185
GestureData = <
item
Control = TabControl1
Collection = <
item
GestureID = sgiLeft
end
item
GestureID = sgiRight
end>
end>
end
object ActionList1: TActionList
Left = 48
Top = 120
object NextTabAction1: TNextTabAction
Category = 'Tab'
end
object PreviousTabAction1: TPreviousTabAction
Category = 'Tab'
end
end
object rsc1: TRESTClient
Accept = 'application/json, text/plain; q=0.9, text/html;q=0.8,'
AcceptCharset = 'utf-8, *;q=0.8'
BaseURL =
'https://bs3winlz02.execute-api.ap-southeast-1.amazonaws.com/v0/d' +
'bqueries'
Params = <>
Left = 136
Top = 120
end
object rsq1: TRESTRequest
Client = rsc1
Params = <>
Response = rsp1
SynchronizedEvents = False
Left = 136
Top = 184
end
object rsp1: TRESTResponse
ContentType = 'application/json'
Left = 136
Top = 248
end
object rsd1: TRESTResponseDataSetAdapter
Active = True
Dataset = mtb1
FieldDefs = <>
Response = rsp1
Left = 136
Top = 312
end
object mtb1: TFDMemTable
Active = True
FieldDefs = <
item
Name = 'meta'
DataType = ftWideString
Size = 255
end>
IndexDefs = <>
FetchOptions.AssignedValues = [evMode]
FetchOptions.Mode = fmAll
ResourceOptions.AssignedValues = [rvSilentMode]
ResourceOptions.SilentMode = True
UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates]
UpdateOptions.CheckRequired = False
UpdateOptions.AutoCommitUpdates = True
StoreDefs = True
Left = 136
Top = 376
end
object bdr1: TBindSourceDB
DataSet = mtb1
ScopeMappings = <>
Left = 136
Top = 440
end
object bdl1: TBindingsList
Methods = <>
OutputConverters = <>
Left = 20
Top = 5
object lcf1: TLinkListControlToField
Category = 'Quick Bindings'
DataSource = bdr1
FieldName = 'meta'
Control = lsv1
FillExpressions = <>
FillHeaderExpressions = <>
FillBreakGroups = <>
end
object lcf3: TLinkListControlToField
Category = 'Quick Bindings'
DataSource = bdr3
FieldName = 'brandname'
Control = lsv3
FillExpressions = <
item
SourceMemberName = 'brand'
ControlMemberName = 'Detail'
end>
FillHeaderExpressions = <>
FillBreakGroups = <>
end
object lcf2: TLinkListControlToField
Category = 'Quick Bindings'
DataSource = bdr2
FieldName = 'name'
Control = lsv2
FillExpressions = <
item
SourceMemberName = 'brand'
ControlMemberName = 'Detail'
end>
FillHeaderExpressions = <>
FillBreakGroups = <>
end
end
object rsc2: TRESTClient
Accept = 'application/json, text/plain; q=0.9, text/html;q=0.8,'
AcceptCharset = 'utf-8, *;q=0.8'
BaseURL =
'https://nm5c906csg.execute-api.ap-southeast-1.amazonaws.com/v0/d' +
'bqueries?search-item=sage'
Params = <>
Left = 200
Top = 120
end
object rsq2: TRESTRequest
Client = rsc2
Params = <>
Response = rsp2
SynchronizedEvents = False
Left = 200
Top = 184
end
object rsp2: TRESTResponse
ContentType = 'application/json'
Left = 200
Top = 248
end
object rsd2: TRESTResponseDataSetAdapter
Active = True
Dataset = mtb2
FieldDefs = <>
Response = rsp2
Left = 200
Top = 312
end
object mtb2: TFDMemTable
Active = True
FieldDefs = <
item
Name = 'brand'
DataType = ftWideString
Size = 255
end
item
Name = 'name'
DataType = ftWideString
Size = 255
end
item
Name = 'description'
DataType = ftWideString
Size = 255
end>
IndexDefs = <>
FetchOptions.AssignedValues = [evMode]
FetchOptions.Mode = fmAll
ResourceOptions.AssignedValues = [rvSilentMode]
ResourceOptions.SilentMode = True
UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates]
UpdateOptions.CheckRequired = False
UpdateOptions.AutoCommitUpdates = True
StoreDefs = True
Left = 200
Top = 376
end
object bdr2: TBindSourceDB
DataSet = mtb2
ScopeMappings = <>
Left = 200
Top = 440
end
object mtb3: TFDMemTable
Active = True
FetchOptions.AssignedValues = [evMode]
FetchOptions.Mode = fmAll
ResourceOptions.AssignedValues = [rvSilentMode]
ResourceOptions.SilentMode = True
UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates]
UpdateOptions.CheckRequired = False
UpdateOptions.AutoCommitUpdates = True
Left = 264
Top = 376
object strngfldmtb3brandname: TStringField
FieldName = 'brandname'
Size = 200
end
object strngfldmtb3brand: TStringField
FieldKind = fkLookup
FieldName = 'brand'
LookupDataSet = mtb2
LookupKeyFields = 'name'
LookupResultField = 'brand'
KeyFields = 'brandname'
Size = 200
Lookup = True
end
end
object bdr3: TBindSourceDB
DataSet = mtb3
ScopeMappings = <>
Left = 264
Top = 440
end
end
The error lies on the LookUp field I created in the FDMemTable (mtb3). I avoided those. Instead, I create a normal data field and directly took the data from TListView (lsv2) as shown below:
FMX Procedure
procedure TTabbedwithNavigationForm.btn1Click(Sender: TObject);
var
brandname, brand : string;
begin
brandname := mtb2.Lookup('name', lsv2.Items[lsv2.ItemIndex].Text, 'name');
brand := mtb2.Lookup('name', lsv2.Items[lsv2.ItemIndex].Text, 'brand');
if mtb3.Locate('brandname', brandname, []) = False then
begin
mtb3.DisableControls;
mtb3.Append;
mtb3.FieldByName('brandname').AsString := brandname;
mtb3.FieldByName('brand').AsString := brand; //manually coded instead of lookup field in the fdmemtable (mtb3)
mtb3.EnableControls;
mtb3.Post;
end;
end;
FMX File
object mtb3: TFDMemTable
Active = True
FieldDefs = <
item
Name = 'brandname'
DataType = ftString
Size = 200
end
item
Name = 'brand'
DataType = ftString // defined as data instead of lookup
Size = 100
end>
IndexDefs = <>
FetchOptions.AssignedValues = [evMode]
FetchOptions.Mode = fmAll
ResourceOptions.AssignedValues = [rvSilentMode]
ResourceOptions.SilentMode = True
UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates]
UpdateOptions.CheckRequired = False
UpdateOptions.AutoCommitUpdates = True
StoreDefs = True
Left = 264
Top = 376
object strngfldmtb3brandname: TStringField
FieldName = 'brandname'
Size = 200
end
object strngfldmtb3brand: TStringField
FieldName = 'brand'
Size = 100
end
end

How to access nested style control

I have custom styled FireMonkey control. Its style contains several levels of nested controls.
I need to access those controls and change some style properties at run-time. To do that I am using FindStyleResource<T> method.
I have no problem in retrieving first level of controls inside style. But accessing controls on second level with FindStyleResource fails if control parent is descendant of TStyledControl.
Question is how to access those nested style controls regardless of their parent type?
Style:
object TStyleContainer
object TLayout
StyleName = 'MyHeader'
Align = Center
Size.Width = 100.000000000000000000
Size.Height = 50.000000000000000000
Size.PlatformDefault = False
Visible = False
TabOrder = 0
object TLabel
StyleName = 'title'
Align = Client
StyledSettings = [Style]
Size.Width = 36.000000000000000000
Size.Height = 50.000000000000000000
Size.PlatformDefault = False
TextSettings.HorzAlign = Center
Text = 'Title'
end
object TLayout
StyleName = 'green'
Align = MostLeft
Size.Width = 32.000000000000000000
Size.Height = 50.000000000000000000
Size.PlatformDefault = False
object TPath
StyleName = 'greenpath'
Align = Fit
Data.Path = {
07000000000000000000404100000041010000000000C0400000604101000000
B81EED405C8F76410100000000004041AE472D410100000052B884415C8F7641
010000000000904100006041030000000000404100000041}
Fill.Color = claGreen
HitTest = False
Size.Width = 32.000000000000000000
Size.Height = 50.000000000000000000
Size.PlatformDefault = False
Stroke.Kind = None
WrapMode = Fit
end
end
object TSpeedButton
StyleName = 'red'
Align = MostRight
Position.X = 68.000000000000000000
Size.Width = 32.000000000000000000
Size.Height = 50.000000000000000000
Size.PlatformDefault = False
object TPath
StyleName = 'redpath'
Align = Fit
Data.Path = {
07000000000000000000404100000041010000000000C0400000604101000000
B81EED405C8F76410100000000004041AE472D410100000052B884415C8F7641
010000000000904100006041030000000000404100000041}
Fill.Color = claRed
HitTest = False
Size.Width = 32.000000000000000000
Size.Height = 32.571426391601560000
Size.PlatformDefault = False
Stroke.Kind = None
WrapMode = Fit
end
end
end
end
Control:
type
TMyHeader = class(TStyledControl)
protected
procedure ApplyStyle; override;
function GetDefaultStyleLookupName: string; override;
end;
procedure TMyHeader.ApplyStyle;
var
LGreen: TLayout;
LGreenPath: TPath;
LRed: TSpeedButton;
LRedPath: TPath;
begin
inherited;
if FindStyleResource<TLayout>('green', LGreen) then
begin
// following call will find greenpath control
if FindStyleResource<TPath>('greenpath', LGreenPath) then
LGreenPath.Fill.Color := TAlphaColorRec.Blue;
end;
if FindStyleResource<TSpeedButton>('red', LRed) then
begin
// following call will fail to find find redpath control
if FindStyleResource<TPath>('redpath', LRedPath) then
LRedPath.Fill.Color := TAlphaColorRec.Blue;
// this variant also fails
if LRed.FindStyleResource<TPath>('redpath', LRedPath) then
LRedPath.Fill.Color := TAlphaColorRec.Blue;
end;
end;
function TMyHeader.GetDefaultStyleLookupName: string;
begin
Result := 'MyHeader';
end;
Original style:
Changed style (only green arrow color was successfully changed)
In ApplyStyle method I can access greenpath from the style and change its color to blue. Hoewever, I cannot get redpath using FindStyleResource method.
The standard way to access style elements is via TFMXObject and iterate the children style objects.
Try this:
procedure TMyHeader.ApplyStyle;
var
objFMX,
inObjFMX: TFMXObject;
LRed: TSpeedButton;
LRedPath: TPath;
begin
inherited;
objFMX:=FindStyleResource('red');
if assigned(objFMX) and (objFMX is TSpeedButton) then
begin
LRed:=objFMX as TSpeedButton;
inObjFMX:=LRed.FindStyleResource('redpath');
if assigned(inObjFMX) and (inObjFMX is TPath) then
begin
LRedPath:=inObjFMX as TPath;
LRedPath.Fill.Color := TAlphaColorRec.Blue;
end;
end
end;
Updated Code: The FindStyleResource does not work in the above code. A different approach is followed below.
procedure TMyHeader.ApplyStyle;
var
objFMX,
inObjFMX: TFMXObject;
LRedPath: TPath;
begin
inherited;
objFMX:=FindStyleResource('red');
if assigned(objFMX) and (objFMX is TSpeedButton) then
begin
for inObjFMX in objFMX.Children do
begin
if inObjFMX is TPath then
begin
LRedPath:=inObjFMX as TPath;
LRedPath.Fill.Color:=TAlphaColorRec.Blue;
Break;
end;
end;
end;
end;
That works on 10.2

Scrolling text effect in Firemonkey

There are moments that I need to present a message for the user and the length of the message is bigger than the space available.
It does not matter which control to be used, I am looking for a way to know when the text is not fully visible and how to apply a scrolling effect (to be more precise scroll the text to the left slowly until all the hidden text is shown and repeat all over again forever).
I am using Delphi XE7.1
Scrolling marquee in Delphi XE7 using standard RTL controls:
procedure TForm1.Button1Click(Sender: TObject);
begin
FloatAnimation1.Enabled := True;
FloatAnimation1.StartValue := Form1.Width;
FloatAnimation1.StopValue := 0-Label1.Width;
end;
object Label1: TLabel
AutoSize = True
Position.X = 240.000000000000000000
Position.Y = 232.000000000000000000
Size.Width = 37.000000000000000000
Size.Height = 16.000000000000000000
Size.PlatformDefault = False
TextSettings.WordWrap = False
Text = 'Label1'
object FloatAnimation1: TFloatAnimation
Duration = 1.000000000000000000
Loop = True
PropertyName = 'Position.X'
StartValue = 0.000000000000000000
StartFromCurrent = True
StopValue = 0.000000000000000000
end
end
object Button1: TButton
Position.X = 248.000000000000000000
Position.Y = 312.000000000000000000
TabOrder = 1
Text = 'Button1'
OnClick = Button1Click
end

Delphi insert image to database firebird

i have table (employee) with many fields.
first name, last name, middle name, image and so on.
i'm using dbExpress (TclientDataset) and have code in the event After Post
clientdataset1.applyupdates(0)
and it works but i want to insert/update also the image but it doesn't save the image to database(Fire bird)
id search in google but it doesn't fit to what i want, please help thanks
Below is the source and DFM of a project I've put together to see if I get the same problem as you.
I don't. It successfully loads and saves .BMP files to the CDS1Image field.
You didn't say what your column type is, but in my FB db, the Image column is defined as a BLOB.
Btw, I'm not sure what kind of image you're trying to work with, but there is a long-standing problem that TDBImage doesn't handle JPEGs.
procedure TForm2.GetImage;
var
ImageFN : String;
MS : TMemoryStream;
begin
if OpenDialog1.Execute then begin
ImageFN := OpenDialog1.FileName;
end;
MS := TMemoryStream.Create;
MS.LoadFromFile(ImageFN);
MS.Seek(0, soBeginning);
try
CDS1.Edit;
CDS1Image.LoadFromStream(MS);
CDS1.Post;
finally
MS.Free;
end;
end;
procedure TForm2.RefreshCDS;
begin
CDS1.ApplyUpdates(0);
CDS1.Close;
CDS1.Open;
end;
procedure TForm2.CDS1NewRecord(DataSet: TDataSet);
var
ID : Integer;
begin
Inc(ID);
if SqlQuery2.Active then
SqlQuery2.Close;
SqlQuery2.Open;
ID := 1 + SqlQuery2.Fields[0].AsInteger;
CDS1.FieldByName('ID').AsInteger := ID;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
CDS1.Open;
end;
procedure TForm2.btnGetImageClick(Sender: TObject);
begin
GetImage;
end;
procedure TForm2.btnRefreshClick(Sender: TObject);
begin
RefreshCDS;
end;
DFM
object Form2: TForm2
Left = 256
Top = 95
Caption = 'Form2'
ClientHeight = 303
ClientWidth = 452
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object DBGrid1: TDBGrid
Left = 8
Top = 8
Width = 320
Height = 120
DataSource = DataSource1
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'Tahoma'
TitleFont.Style = []
end
object DBNavigator1: TDBNavigator
Left = 24
Top = 144
Width = 240
Height = 25
DataSource = DataSource1
TabOrder = 1
end
object btnRefresh: TButton
Left = 350
Top = 8
Width = 75
Height = 25
Caption = 'Refresh'
TabOrder = 2
OnClick = btnRefreshClick
end
object DBImage1: TDBImage
Left = 128
Top = 175
Width = 105
Height = 105
DataField = 'IMAGE'
DataSource = DataSource1
TabOrder = 3
end
object btnGetImage: TButton
Left = 350
Top = 64
Width = 75
Height = 25
Caption = 'GetImage'
TabOrder = 4
OnClick = btnGetImageClick
end
object SQLConnection1: TSQLConnection
DriverName = 'Firebird'
LoginPrompt = False
Params.Strings = (
'DriverUnit=Data.DBXFirebird'
'DriverPackageLoader=TDBXDynalinkDriverLoader,DbxCommonDriver180.' +
'bpl'
'DriverAssemblyLoader=Borland.Data.TDBXDynalinkDriverLoader,Borla' +
'nd.Data.DbxCommonDriver,Version=18.0.0.0,Culture=neutral,PublicK' +
'eyToken=91d62ebb5b0d1b1b'
'MetaDataPackageLoader=TDBXFirebirdMetaDataCommandFactory,DbxFire' +
'birdDriver180.bpl'
'MetaDataAssemblyLoader=Borland.Data.TDBXFirebirdMetaDataCommandF' +
'actory,Borland.Data.DbxFirebirdDriver,Version=18.0.0.0,Culture=n' +
'eutral,PublicKeyToken=91d62ebb5b0d1b1b'
'GetDriverFunc=getSQLDriverINTERBASE'
'LibraryName=dbxfb.dll'
'LibraryNameOsx=libsqlfb.dylib'
'VendorLib=fbclient.dll'
'VendorLibWin64=fbclient.dll'
'VendorLibOsx=/Library/Frameworks/Firebird.framework/Firebird'
'Database=d:\delphi\firebird\databases\employee.fdb'
'User_Name=sysdba'
'Password=masterkey'
'Role=RoleName'
'MaxBlobSize=-1'
'LocaleCode=0000'
'IsolationLevel=ReadCommitted'
'SQLDialect=3'
'CommitRetain=False'
'WaitOnLocks=True'
'TrimChar=False'
'BlobSize=-1'
'ErrorResourceFile='
'RoleName=RoleName'
'ServerCharSet='
'Trim Char=False')
Connected = True
Left = 40
Top = 24
end
object SQLQuery1: TSQLQuery
MaxBlobSize = 1
Params = <>
SQLConnection = SQLConnection1
Left = 112
Top = 24
end
object DataSource1: TDataSource
DataSet = CDS1
Left = 272
Top = 88
end
object CDS1: TClientDataSet
Active = True
Aggregates = <>
CommandText = 'select * from maimages'
Params = <>
ProviderName = 'DataSetProvider1'
AfterOpen = CDS1AfterOpen
OnNewRecord = CDS1NewRecord
Left = 280
Top = 24
object CDS1ID: TIntegerField
FieldName = 'ID'
Required = True
end
object CDS1NAME: TStringField
FieldName = 'NAME'
Size = 50
end
object CDS1IMAGE: TBlobField
FieldName = 'IMAGE'
Size = 1
end
end
object DataSetProvider1: TDataSetProvider
DataSet = SQLQuery1
Options = [poAllowCommandText, poUseQuoteChar]
Left = 184
Top = 24
end
object OpenDialog1: TOpenDialog
Filter = 'BMPs|*.Bmp'
Left = 400
Top = 32
end
object SQLQuery2: TSQLQuery
Active = True
MaxBlobSize = 1
Params = <>
SQL.Strings = (
'select max(ID) from maimages')
SQLConnection = SQLConnection1
Left = 16
Top = 120
end
end

Resources