Jump to content
PeterPanettone

TcheckListBox: Hiding the Values?

Recommended Posts

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

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 by Mahdi Safsafi
  • Thanks 1

Share this post


Link to post

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.

 

  • Like 2

Share this post


Link to post
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
3 hours ago, aehimself said:

I don't feel fine storing information in the UI.

That's what I call "user-centric" programming. :classic_smile:

 

And BTW, the stored information is HIDDEN by using the code of @Mahdi Safsafi

Edited by PeterPanettone

Share this post


Link to post
1 minute ago, PeterPanettone said:

That's what I call "user-centric" programming. :classic_smile:

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.

  • Like 2

Share this post


Link to post
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 by PeterPanettone

Share this post


Link to post

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

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

That's why I love PROGRAMMING: It's ABSOLUTE FREEDOM as opposed to the old [political terms removed by OP] rule.

Edited by PeterPanettone
  • Haha 1

Share this post


Link to post

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.

  • Like 1

Share this post


Link to post
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 by PeterPanettone

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×