-
Content Count
311 -
Joined
-
Last visited
-
Days Won
1
Posts posted by Serge_G
-
-
1 hour ago, erva said:I'am using FormatDateTime('dd.mm.yyyy', %s) and get error "Invalid class typecast".
%s is yet a string so it's somewhere normal
Try FormatDateTime('dd.mm.yyyy',value)
or declare your fields, set your date field displayformat property to 'dd.mm.yyyy' and use displaytext in customformat
- 1
-
Sorry, not being specific. Late I found, really by chance, why the code I used
procedure TForm110.btnDetailClick(Sender: TObject); // numeric sort on detail var Compare : TFMXObjectSortCompare; begin Tri:=btnDetail.Tag; if btnDetail.Tag=1 then btnDetail.Tag:=0 else btnDetail.Tag:=1; ListBox1.Sorted:=False; Compare:=function(item1, item2: TFmxObject): Integer var n1,n2 : Single; begin n1:=StrToFloatDef(TListBoxItem(item1).ItemData.Detail,0); n2:=StrToFloatDef(TListBoxItem(item2).ItemData.Detail,0); if n2=n1 then result:=0 else begin if n2>n1 then Result := 1 else Result := -1; end; if tri=0 then result:=result*-1; end; ListBox1.Sort(Compare); // here end;
seems to be useless.
Just resizing the form (to take a picture) 'refreshed' the aligned list. Before solving, I used a BeginUpdate/EndUpdate sequence with no effect ! So that was why I don't understood the usage of list.sort(compare) was not 'working'. A self.width:=self.width+1; self.width:=self.width; confirmed that but was not the solution.
Finally, digging in the source code, I found the solution
ListBox1.RealignContent;
Just after the sort did it.
Joined, comparative runtime screens (first alpha sort on text using sorted:=true, second numeric sort on detail using sort(compare) twice to have DESC order)
- 1
-
Hi,
I found a way to sort my lists using Sort an OnCompare event but I don't figure out a functional way to use Sort(Compare) method (Rio 10.3.3)
Any clues ?
Thanks
-
On 4/8/2020 at 8:34 PM, bazzer747 said:So a 'close' on the query does what exactly (in terms of any SQL code in the query)?
A close no, but an unprepare should be to check. If your first SQL works, other request just changing parameter works. i.e dm.fdq.Open('',[ 2 ] );
It's when you change the SQL and parameters the problem.
-
19 hours ago, Tntman said:Short answer is that I am afraid to code that by myself because I am scared of making it crappy and inefficient but I guess it is the learning curve ...
Well don't be so afraid. I think you can use a TFrame (somewhere TFrame is like a style) for all that filling stuff. I think it was the Paul Toth approach.
- 1
-
Hi,
I never thought about including animation in a ListView but, why not 😉
However my guess is TListView is not a good candidate for this sort of usage. Instead think about the ancestor, a TScrollBox.
In my mind, this Jaques Nascimento video or videos from CodeRage2019 (Paul Thoth and Adriano Santos interventions)
- 2
-
Hello,
This was a question I had in mind for a long time. I used to use, like ergeka
and, even, closing the query before (old BDE comportment)
dm.fdc.Close; dm.fdc.parambyname('Pc').asString:='Woolworths'; dm.fdc.Open;
So, today, I make a little test and Firedac is really an amazing thing
dm.fdc.Open,('',[ 'Woolworths' ]);
works. One only line versus 2 (three in my case) and shorter than this ParambyName stuff.
I certainly use this for now 😉
By the way I test also this query
Select * from tTable where Company = ? order by oOrderName
a no named parameter. It works too 👍
-
An argument : Firedac is BDE like (this mean all the old "BDE code" could be used as is) but is much more 😉
-
Hi,
You are not alone 😉 even if BDE is largely obsolete I still have some fights with it.
My suggestions to use it in a MS UAC environment (from Vista and more) :
Don't use "program files" folders, install it in a root base directory (i.e. c:\borland\BDE)
After install change some options :
NET DIR directory (configuration/native/Paradox
SHAREMEMxx values (configuration/system/init) (check this document for values)
Last, don't forget to put Object/Options/ save for use with windows 3.1 and windows 95/NT << yes this can be a bit strange and prove obsolescence, as far as I understand this indicates BDE to find IDAPI32.cfg file and not in registry ,
as you certainly knows registry, UAC and users are not very friendly
Installing BDE ? I use a setup I found with one of my older Delphi version (D2010 I think), but some installers (don't know if it's legal) can be found on the web i.e here or there
be aware that BDE installer from Code Central need IDE to be installed on the PC
I use version 5.0.1, note : last version was 5.2 I think
15 hours ago, Antony Danby said:Oh, I think you are right about FireDAC, but the customer is a bit adverse to it at the moment and wants to spread the "risk" out a bit and I can't blame them to be honest.
I can't understand this, Firedac is much more than BDE ! Ok, if they still use paradox, db tables but wow ...
- 1
-
You can simplify all this, at design time the link is well known and named (LinkGridtodatasourcexxxxxx).
Just rename your link in the BindingsList to grZasobaLink
-
20 hours ago, Vandrovnik said:Thank you for helping me to get the right way!
A pleasure 😉 .
But this still does not satisfy me fully, so I persist.
My goal was to have the members linked even if no columns were defined, I found a way applying the principle : "if no columns are defined then all fields of the datasource are displayed".
Having the linked datasource is easy TLinkGridToDatasource(B).DataSource, having the member list not so but I found that TBaseObjectBindSource have an interface IScopeMemberNames
private ColumnList : TStringList; procedure TForm1.Button1Click(Sender: TObject); var B : TContainedBindComponent; SL : TStringList; S : String; IMembers : IScopeMemberNames; ib : integer; begin for ib:=0 to BindingsList1.BindCompCount-1 do begin B:=BindingsList1.BindComps[ib]; if (B.ControlComponent is TCustomGrid) then begin if TBaseObjectBindSource(TLinkGridToDatasource(B).DataSource).GetInterface(IScopeMemberNames,IMembers) then begin IMembers.GetMemberNames(ColumnList); for S in ColumnList do Memo1.Lines.Add(S); end; end; end; end;
Now it's just a question of using a StringList to store the fieldnames and to arrange it function of the grid (defined columns, and move), more "classic code" I think even if, at this time, I have no idea (Sunday not propitious to )
P.S.
QuoteBut does not keep column width, when user changes the width in runtime
The only way I think about is to have a sort of SaveGridSettings / LoadGridSettings procedure
something using ObjectBinaryToText and reverse
function SaveGridSettings(Component: TComponent): string; var BinStream:TMemoryStream; StrStream: TStringStream; s: string; begin BinStream := TMemoryStream.Create; try StrStream := TStringStream.Create(s); try BinStream.WriteComponent(Component); BinStream.Seek(0, soFromBeginning); ObjectBinaryToText(BinStream, StrStream); StrStream.Seek(0, soFromBeginning); Result:= StrStream.DataString; finally StrStream.Free; end; finally BinStream.Free end; end;
-
Agree with NIRAV KAKU in the principle but anyway if you want to access LiveBinded fieldname of a column, fieldname is the wrong name you have to search a membername.
My test in ideal conditions (only one StringGrid, only Stringgrid is Binded)
Consider this code, list of all columns linked
procedure TForm1.Button1Click(Sender: TObject); var B : TContainedBindComponent; C : TLinkGridToDataSourceColumns; ib,ic : integer; begin // have to search in the whole bindingslist for ib:=0 to BindingsList1.BindCompCount-1 do begin B:=BindingsList1.BindComps[ib]; // check if the component is the stringgrid if (B.ControlComponent=StringGrid1) then begin // look for all linked columns for ic := 0 to TLinkGridToDatasource(B).Columns.Count-1 do begin C :=TLinkGridToDataSourceColumns(TLinkGridToDatasource(B).Columns); Memo1.lines.add(c[ic].MemberName); end; end; end; end;
From this you can write a function, something like function FieldNameOfGrid(const Grid : TCustomGrid; col : integer) : String
function TForm100.FieldNameOfGridCol(const Grid: TcustomGrid; const col: Integer): String; var B : TContainedBindComponent; ib : integer; begin for ib:=0 to BindingsList1.BindCompCount-1 do begin B:=BindingsList1.BindComps[ib]; if (B.ControlComponent=Grid) then try result:=TLinkGridToDataSourceColumns(TLinkGridToDatasource(B).Columns)[col].MemberName; break; except result:=''; end; end; end;
Perfectible I think but working, even with unlinked columns, but only if columns are defined
- 1
-
Hi,
QuoteIt works for Windows, iOS and Android but not for macOS-64
sounds strange, but I am not an apple owner
1 hour ago, sjordi said:CustomFormat to DisplayFormat
Hum, you want to say DisplayText ?
1 hour ago, sjordi said:But the CustomFormat should be set to Format('%%.2f', %s)
I report, I think about two times https://quality.embarcadero.com/browse/RSP-22962 , this bug. If you want to use the format of livebindings try to use
Format('%%.2f', 1*value)
-
Hum !
I was convinced my picture explain the whole thing
In my sample (pro app i'm writing) it's work, and description you gave seem to be the same goal.
I resume : a TListview (live)binded to a BindSourceDB, linked to a Dataset (whatever could it be Firedac, ClientDataset even TProtypeBindSource) fields of this one declared and some, here your currency field, with their DisplayFormat set.
Take care one thing, you have to change those 'displaytext' in the FillExpressions collection
one or more picture to see where you encounter difficulties (even a dfm part of the form) should be a good thing
ie.
object bndngslst1: TBindingsList Methods = <> OutputConverters = <> Left = 20 Top = 5 object LinkListControlToField1: TLinkListControlToField Category = 'Liaisons rapides' DataSource = bndQFacture Control = lvFactures FillExpressions = < item SourceMemberName = 'ANNEE' ControlMemberName = 'NumeroFacture' CustomFormat = '%s+'#39'-'#39'+DataSet.NUMERO.Text+'#39' ('#39'+DataSet.PART.Text+'#39')'#39 end item SourceMemberName = 'NOM' ControlMemberName = 'Client' end item SourceMemberName = 'ECHEANCE' ControlMemberName = 'Echeance' CustomFormat = 'DisplayText+'#39' '#39'+Dataset.MODE_PAIEMENT.Text' end item SourceMemberName = 'MONTANT' ControlMemberName = 'Montant' end> FillHeaderExpressions = <> FillBreakGroups = <> end end
-
-
On 1/9/2020 at 6:02 PM, Yaron said:I have "ListView.ItemAppearanceObject.ItemObjects.Detail.Visible = False" and "ListView.ItemAppearanceObject.ItemEditObjects.Detail.Visible = False".
And "ListView.ItemAppearance" set to "ListItem" (which adds a ">" at the end of the line for some reason).
Hi, you forgot to set image and accessory not visible.
-
Well, sorry if it's too late, i saw this post today.
"Yes you can" , playing with the ItemHeight, alas this height is an integer and can't be lesser than 1 (0 => default size) so you will obtain a gray gap more or less high depending on items count in the group
I explain how in this blogpost (sorry french only)
- 1
-
You have one linked to my blog post. To see the behavior that I denounce, you only have to use livebindings editor and synchronize,accepting link change, and renaming this new link (not fair hu ?)
On the other hand, i am working on another sample (using the well-known biolife.cds) but it is not ready yet, mainly because i have some other functionalities (i.e. custom search)
Here some screenshots (capture and capture_1 without synchronization, last one with synchronization) , same code
procedure TMainForm.rdbListBoxChange(Sender: TObject); var AFillBreakGroup : TFillBreakGroupItem; begin LinkListBoxGroup.Active:=False; if TRadioButton(Sender).IsChecked then begin case TRadioButton(Sender).tag of 0 : begin LinkListBoxGroup.FillBreakGroups.Clear; LinkListBoxGroup.FillBreakFieldName:=''; LinkListBoxGroup.FillHeaderFieldName:=''; ClientDataSet1.IndexFieldNames:=''; end; 1 : begin LinkListBoxGroup.FillBreakGroups.Clear; LinkListBoxGroup.FillBreakFieldName:='Category'; LinkListBoxGroup.FillHeaderFieldName:='Category'; ClientDataSet1.IndexFieldNames:='Category'; end; 2 : begin ClientDataSet1.IndexFieldNames:='Length (cm)'; LinkListBoxGroup.FillBreakFieldName:='Length (cm)'; LinkListBoxGroup.FillHeaderFieldName:=''; // créer les groupes aFillBreakGroup:=LinkListBoxGroup.FillBreakGroups.AddItem; AFillBreakGroup.MinValue:='0'; AFillBreakGroup.MaxValue:=30.ToString; AFillBreakGroup.DisplayText:='Petits'; aFillBreakGroup:=LinkListBoxGroup.FillBreakGroups.AddItem; AFillBreakGroup.MinValue:=30.ToString; AFillBreakGroup.MaxValue:=60.toString; AFillBreakGroup.DisplayText:='Moyens'; aFillBreakGroup:=LinkListBoxGroup.FillBreakGroups.AddItem; AFillBreakGroup.MinValue:=60.ToString; AFillBreakGroup.MaxValue:=90.ToString; AFillBreakGroup.DisplayText:='Gros'; aFillBreakGroup:=LinkListBoxGroup.FillBreakGroups.AddItem; AFillBreakGroup.MinValue:=90.ToString; AFillBreakGroup.DisplayText:='Enormes'; end; end; end; LinkListBoxGroup.Active:=True; end;
-
Hi,
Pushing limits of TListBox and TListView I am testing FillBreakGroups collection (you can see my firsts steps here).
Ok, that works fine was my first thoughts.
Writing a new tutorial about list and livebindings, I create a new project and saw that using synchronize link and FillBreakGroups does not work is this not supposed to or is this a bug ?
note : my tests are only on 10.3.2 version
-
14 hours ago, limelect said:@Alexander Sviridenkov Then is this guy wrong ?
https://serge-girard.developpez.com/tutoriels/Delphi/Livebindings/Grilles/#LVII-C-1
Yes, I only check for windows not for other platforms. I think Interface IFMXTextService and DrawSingleLine is a track to follow, but I am blocked with this Font argument (needed to be retrieve in style ?)
- 1
-
If you only check for those 2 alternatives and only windows target my heart say Firebird as Dany Marmur I had no problem with since first version.
if you want some encrypted column the choice is Interbase (native column encryption).
Now if your targets are multi os, till now i don't access directly to Firebird database (client/server) on Android with Firedac but it works with IBDac. I don't test an embedded version of the database though.
So for multi-os I certainly will choose IB keeping in mind Firebird .
But if your project is not a multi-user one i vote for SQLite avoiding all database server deployment
- 1
-
What about using TTextService ?
I just had a (deep) look into Delphi source and found TTextServiceAndroid.DrawSingleLine
{$IFDEF ANDROID} if SupportsPlatformService(IFMXTextService,aService) then begin alignement:=CheckRtl(Value.ToString,''); if alignement=TTextAlign.Trailing then flag := [TFillTextFlag.RightToLeft] else flag:=[]; // had to get font aService.DrawSingleLine(Canvas,Value.ToString,Bounds,Afont, 1,flag, alignement); end; {$ENDIF}
My only problem is to get the right font though (the one in the style i presume).
I don't go further with this for now..
-
Oh, it seem that was the TTextLayout.RighttoLeft who do the trick but did not work for Android 😣 and I do not know if it works for those Apple things
My friend Nabil just send me an intyeresting link
- 1
-
Hi,
I don't write nor read RTL languages, I wrote a function to detect if the text starts with a RTL char
function checkRtl (S : string; Exceptions : String = '' ) : TTextAlign; var carray : array of WideChar; i : int64; ws : String; begin for I := 0 to 9 do S:=StringReplace(S,i.ToString,'',[rfReplaceAll]); // supprime autres caractères spéciaux S:=StringReplace(S,'(','',[rfReplaceAll]); S:=StringReplace(S,')','',[rfReplaceAll]); S:=StringReplace(S,'"','',[rfReplaceAll]); S:=StringReplace(S,'''','',[rfReplaceAll]); S:=StringReplace(S,'-','',[rfReplaceAll]); if not E.IsEmpty then begin for I := 1 to Length(Exceptions) do S:=StringReplace(S,Exceptions[i],'',[rfReplaceAll]); end; S:=Trim(S); // arabic + hebrew SetLength(carray,$6ff-$590); for I := $590 to $6ff do carray[i-$590]:=Char(I); // there are some farsi char to be added result:=TTextAlign.Trailing; if S.IsEmpty then exit; if inOpArray(S[1],carray) then result:=TTextAlign.Leading; end;
And, with Nabil's Help I test my ideas in a grid.
You can find (french) discussion here and my tutorial https://serge-girard.developpez.com/tutoriels/Delphi/Livebindings/Grilles/#LVII-C-1
I did not test for TEdit and TLabel though but my guess it is possible
- 1
- 2
Programmatically Change Properties of a Custom style
in FMX
Posted
As I understand what is in your mind, I think it's your ChangeObjectRecursive function the problem.
A component (your panel) as style but style is not the "container" of the panel's childs.
And therefore, you change wrong "styledata" property for a label
See this :