PeterPanettone 158 Posted July 15, 2020 In Delphi 10.4, I fill a TCheckListBox in a loop adding name= value pairs: for i := 1 to 32 do CheckListBox1.Items.AddPair(GetName(i), GetValue(i)); Of course, the CheckListBox then shows: Quote Name1=Value1 Name2=Value2 Name3=Value3 etc. Well, is there a "trick" to show only the NAMES and HIDE the VALUES in the CheckListBox? I would like to avoid AddObject or messing around with multiple string-lists. Any idea? Share this post Link to post
Mahdi Safsafi 225 Posted July 15, 2020 (edited) For me I'd go with AddObject as its better than using Pair<Name, Value>. However you can either set CheckListBox1.Style to lbVirtual and then handle all data event. Or simply set Style to lbOwnerDrawFixed and owner draw your control: // CheckListBox1.Style := lbOwnerDrawFixed; procedure TMain.CheckListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); var Flags: Longint; Data: String; FCanvas: TCanvas; CheckListBox: TCheckListBox; begin CheckListBox := TCheckListBox(Control); FCanvas := CheckListBox.Canvas; FCanvas.FillRect(Rect); if Index < CheckListBox.Count then begin Flags := DrawTextBiDiModeFlags(DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX); if not UseRightToLeftAlignment then Inc(Rect.Left, 2) else Dec(Rect.Right, 2); Data := CheckListBox.Items.Names[Index]; DrawText(FCanvas.Handle, Data, Length(Data), Rect, Flags); end; end; EDIT: Removed ExtractName function. Edited July 15, 2020 by Mahdi Safsafi 1 Share this post Link to post
aehimself 399 Posted July 16, 2020 I don't feel fine storing information in the UI. I'd rather create a separate TList<TMyValue> and add the values to it as I'm adding the checkboxes. This way the index of the CheckBox will be equal to the index of it's value in the TList. 2 Share this post Link to post
PeterPanettone 158 Posted July 16, 2020 12 hours ago, Mahdi Safsafi said: set Style to lbOwnerDrawFixed and owner draw your control: Thank you for your code! It's much appreciated! Share this post Link to post
PeterPanettone 158 Posted July 16, 2020 (edited) 3 hours ago, aehimself said: I don't feel fine storing information in the UI. That's what I call "user-centric" programming. And BTW, the stored information is HIDDEN by using the code of @Mahdi Safsafi Edited July 16, 2020 by PeterPanettone Share this post Link to post
aehimself 399 Posted July 16, 2020 1 minute ago, PeterPanettone said: That's what I call "user-centric" programming. In a more advanced project (especially after a UI change or refactoring) you'll quickly realize why separating the UI and data storage/handling extremely important. In your example, let's say a user doesn't like CheckListBox and wants you to change it to something else. Apart from the visual changes, you'll have to re-code your business logic as well. It is not that important in "personal use" applications, but lately I have a separate class for data storage everywhere. The UI only displays, validation, (de)serialization, everything is handled by the class itself. 2 Share this post Link to post
PeterPanettone 158 Posted July 16, 2020 (edited) 5 minutes ago, aehimself said: In a more advanced project (especially after a UI change or refactoring) you'll quickly realize why separating the UI and data storage/handling extremely important. In your example, let's say a user doesn't like CheckListBox and wants you to change it to something else. Apart from the visual changes, you'll have to re-code your business logic as well. Generally, you are right. But in this particular case, it's more a prototype feature/application. Edited July 16, 2020 by PeterPanettone Share this post Link to post
PeterPanettone 158 Posted July 16, 2020 BTW, I wonder why something useful like this is not natively BUILT-IN. TCheckListBox should have a boolean property HideValues which does exactly what Mahdi's code does. Share this post Link to post
aehimself 399 Posted July 16, 2020 Because - TCheckListBox.Items is TStrings, and .Values are supported by TStrings. I would not be surprised if this was not meant to be used as value storage; due to the reason you just very asked. Share this post Link to post
PeterPanettone 158 Posted July 16, 2020 (edited) That's why I love PROGRAMMING: It's ABSOLUTE FREEDOM as opposed to the old [political terms removed by OP] rule. Edited July 16, 2020 by PeterPanettone 1 Share this post Link to post
aehimself 399 Posted July 16, 2020 Yep, you have so much freedom you can easily do Var tb: TBytes; a: Integer; Begin SetLength(tb, 5); For a := 0 To 5 Do tb[a] := 1; End; or... Var pc: PChar; Begin GetMem(pc, 5 + 1); StrPCopy(pc, 'abcde', 5); End; or even: Var obj: TObject; proc: TProcedure; Begin proc := addr(obj); proc; End; Just because you have the possibility of doing something it doesn't mean you are supposed to or should. Btw, I thought this forum is a politic-free area. Please take those ideologies to Reddit. 1 Share this post Link to post
PeterPanettone 158 Posted July 16, 2020 (edited) 58 minutes ago, aehimself said: Just because you have the possibility of doing something it doesn't mean you are supposed to or should. You are completely right. Edited July 16, 2020 by PeterPanettone Share this post Link to post